Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example validation for polymorphic schemas with discriminator/allOf approach #1791

Open
andiahlm opened this issue Oct 31, 2024 · 0 comments

Comments

@andiahlm
Copy link

Is your feature request related to a problem? Please describe.

In our OAS3.1 specifications we make use of the polymorphism and inheritance feature. As you describe in your documentation on how to use discriminator, there are mainly two strategies:

  • oneOf/anyOf in combination with discriminator understood as a 'super schema'
  • discriminator in the 'parent schema' combined with allOf in the 'child schema'

We prefer the allOf approach since it is more suitable with code generators in our context. However in the latter case the properties of the child schemas (Dog and Cat) are not validated. We understand that from a JsonSchema point of view the discriminator is not not/limited supported. Do you have this on the road map to support discriminator based validation of child schema in the allOf context or do you have any other suggestion on how this could be achieved in combination with redocly lint?

Here are two samples of the szenario which both contain an error in the Dog property 'barkSound' (The value is not a member of the enum):
The first implements the oneOf/discriminator strategy with a SuperSchema (PetSuper) and validates the error correctly (Warning was generated by the no-invalid-media-type-examples rule.)
The second implements our preferred discriminator/allOf strategy but does not create an error on validation.
Both were validated with redocly lint and no configuration file.

Example with oneOf/discriminator

openapi: 3.1.0
info:
  title: Example API
  version: 1.0.0
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html
servers:
  - description: Sample Server URL
    url: https://api.usz.ch
security: []
tags: []
paths:
  /pet:
    get:
      summary: This is a summary
      description: This is a description.
      operationId: getPet
      responses:
        '200':
          description: Get pet
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PetSuper'
              examples:
                Cat:
                  value:
                    id: id-of-cat
                    petType: Cat
                    motherPet:
                      id: id-of-mother-cat
                      petType: Cat
                    whiskersLength: 12
                Dog:
                  value:
                    id: id-of-dog
                    petType: Dog
                    motherPet:
                      id: id-of-mother-dog
                      petType: Dog
                      barkSound: Quiet
                    barkSound: VeryLoud
        '400':
          description: Unexpected error
          content:
            application/json:
              schema:
                type: string
components:
  schemas:
    Pet:
      type: object
      properties:
        id:
          type: string
        petType:
          $ref: '#/components/schemas/PetType'
        motherPet:
          $ref: '#/components/schemas/PetSuper'
      required:
        - id
        - petType
    PetSuper:
      oneOf:
        - $ref: '#/components/schemas/Cat'
        - $ref: '#/components/schemas/Dog'
      discriminator:
        propertyName: petType
        mapping:
          Dog: '#/components/schemas/Dog'
          Cat: '#/components/schemas/Cat'
    Cat:
      allOf:
        - $ref: '#/components/schemas/Pet'
        - type: object
          properties:
            whiskersLength:
              type: integer
              description: Length of cat's whiskers
    Dog:
      allOf:
        - $ref: '#/components/schemas/Pet'
        - type: object
          properties:
            barkSound:
              type: string
              description: Sound of dog's bark
              enum:
                - Loud
                - Quiet
    PetType:
      type: string
      description: Type of the Pet
      enum:
        - Cat
        - Dog

Example with discriminator/allOf

openapi: 3.1.0
info:
  title: Pet Polymorph API
  version: 1.0.0
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html
servers:
  - description: Sample Server URL
    url: https://api.sampleurl.ch
security: []
tags: []
paths:
  /pet:
    get:
      summary: This is a summary
      description: This is a description.
      operationId: getPet
      responses:
        '200':
          description: Get pet
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Pet'
              examples:
                Cat:
                  value:
                    id: id-of-cat
                    petType: Cat
                    motherPet:
                      id: id-of-mother-cat
                      petType: Cat
                    whiskersLength: 12
                Dog:
                  value:
                    id: id-of-dog
                    petType: Dog
                    motherPet:
                      id: id-of-mother-dog
                      petType: Dog
                      barkSound: Quiet
                    barkSound: VeryLoud
        '400':
          description: Unexpected error
          content:
            application/json:
              schema:
                type: string
components:
  schemas:
    Pet:
      type: object
      properties:
        id:
          type: string
        petType:
          $ref: '#/components/schemas/PetType'
        motherPet:
          $ref: '#/components/schemas/Pet'
      required:
        - id
        - petType
      discriminator:
        propertyName: petType
        mapping:
          Dog: '#/components/schemas/Dog'
          Cat: '#/components/schemas/Cat'
    Cat:
      allOf:
        - $ref: '#/components/schemas/Pet'
        - type: object
          properties:
            whiskersLength:
              type: integer
              description: Length of cat's whiskers
    Dog:
      allOf:
        - $ref: '#/components/schemas/Pet'
        - type: object
          properties:
            barkSound:
              type: string
              description: Volume of sound of dog's bark
              enum:
                - Loud
                - Quiet
    PetType:
      type: string
      description: Type of the Pet
      enum:
        - Cat
        - Dog

Describe the solution you'd like

We would love redocly lint to validate child schemas based on the discriminator property.

Describe alternatives you've considered

Additional context

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant