yonaskolb / SwagGen

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

Support `discriminator` property is on the model #186

Closed chaseacton closed 4 years ago

chaseacton commented 5 years ago

OpenAPI 3 supports specifying the discriminator on either the model or response objects. Currently SwagGen only works when the discriminator is on the response. When it's on the model, inheritance doesn't work properly, all objects (for example, when parsing an array of objects), are of the base class, not the proper subclasses.

https://swagger.io/docs/specification/data-models/inheritance-and-polymorphism/

yonaskolb commented 5 years ago

Hi @chaseacton. Could you give an example spec or model that doesn’t generate properly

chaseacton commented 5 years ago

Sure, here is a simple example. Notice the generated 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':
          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:
                          cat: '#/components/schemas/Cat'
                          dog: '#/components/schemas/Dog'

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 5 years ago

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

chaseacton commented 4 years ago

@yonaskolb Could you point me to where I would go to add support for this in SwagGen?

yonaskolb commented 4 years ago

Hi @chaseacton. Sorry, I haven’t been across the repo in a little while. I haven’t had a chance to look at this properly. I suspect a workaround (at least for the example above if it doesn’t work) would be to pull out the inline array item schemes into an Animal schema. As it could be that oneOf is not supported in inline schemas at the moment.

Let me know how you go. Otherwise it would need to debugged to find the issue

yonaskolb commented 4 years ago

Hmm, I doubt what I said above is the issue though. I’ll have to check this out

yonaskolb commented 4 years ago

Hi @chaseacton. I had a look at your example above. It was silently failing to parse the response because description was missing. It is required in the spec as can be seen here https://swagger.io/specification/#responseObject I've now made it optional and default to an empty string https://github.com/yonaskolb/SwagGen/pull/193 With a description defined or the PR, your example seems to generate fine. Can you confirm, or are you still having trouble with discriminators?