yonaskolb / SwagGen

OpenAPI/Swagger 3.0 Parser and Swift code generator
MIT License
626 stars 146 forks source link

Generation failing when discriminator is only declared on the base object schema #194

Open chaseacton opened 4 years ago

chaseacton commented 4 years ago

Hi @yonaskolb, I'm back with a new discriminator issue. In this sample spec, the discriminator is only declared on the base Pet object and does not generate correctly. GetPets.Response is empty.


info:
  version: 1.0.0
  title: Example API
  description: >
    This is an example API excercising the discriminator syntax.
​servers:
  - url: http://petstore.swagger.io/v1
paths:
  /pets:
    get:
      responses:
        '200':
          description: fetch a list of pets
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                properties:
                  data:
                    type: array
                    items:
                      '#/components/schemas/Pet'

components:
  schemas:
    Pet:
      type: object
      required:
        - pet_type
      properties:
        pet_type:
          type: string
      discriminator:
        propertyName: pet_type
    Dog:     # "Dog" is a value for the pet_type property (the discriminator value)
      allOf: # Combines the main `Pet` schema with `Dog`-specific properties 
        - $ref: '#/components/schemas/Pet'
        - type: object
          # all other properties specific to a `Dog`
          properties:
            bark:
              type: boolean
            breed:
              type: string
              enum: [Dingo, Husky, Retriever, Shepherd]
    Cat:     # "Cat" is a value for the pet_type property (the discriminator value)
      allOf: # Combines the main `Pet` schema with `Cat`-specific properties 
        - $ref: '#/components/schemas/Pet'
        - type: object
          # all other properties specific to a `Cat`
          properties:
            hunts:
              type: boolean
            age:
              type: integer```
chaseacton commented 4 years ago

Hey @yonaskolb, have you had a chance to look at this?

yonaskolb commented 4 years ago

Hi @chaseacton

Firstly your response is misconfigured: the array items would need to be a $ref

items:
  $ref: '#/components/schemas/Pet'

Then it would generate as Pet and not [String: Any]

Secondly at this time SwagGen does not support using discriminators in allOf class hierarchies, only in oneOf cases.

To get this to work you must declare it like this

paths:
  /pets:
    get:
      responses:
        '200':
          description: fetch a list of pets
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                properties:
                  data:
                    type: array
                    items:
                      oneOf:
                        - $ref: '#/components/schemas/Cat'
                        - $ref: '#/components/schemas/Dog'
                      discriminator:
                        propertyName: pet_type
                        mapping: # only required if pet_type is not Cat and Dog
                          cat: '#/components/schemas/Cat'
                          dog: '#/components/schemas/Dog'

I hope that helps!