swagger-api / swagger-ui

Swagger UI is a collection of HTML, JavaScript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API.
https://swagger.io
Apache License 2.0
26.06k stars 8.87k forks source link

Issue with rendering allOf when components is defined before paths #8291

Open jeroendk opened 1 year ago

jeroendk commented 1 year ago

Q&A (please complete the following information)

Content & configuration

Example Swagger/OpenAPI definition:

openapi: "3.0.0"
info:
  version: 1.0.0
  title: Swagger Petstore
servers:
  - url: /

components:
  schemas:
    Pet:
      allOf:
        - $ref: '#/components/schemas/createPet'
      required:
        - id
      properties:
        id:
          type: integer
    createPet:
      required:
        - name
      properties:
        name:
          type: string
        tag:
          type: string
    Pets:
      type: array
      items:
        $ref: "#/components/schemas/Pet"
  responses:
    listPets:
      description: An array of pets
      content:
        application/json:    
          schema:
            $ref: "#/components/schemas/Pets"
    getPet:
      description: An array of pets
      content:
        application/json:    
          schema:
            $ref: "#/components/schemas/Pet"

paths:
  /pets:
    get:
      summary: List all pets
      responses:
        '200':
          "$ref": "#/components/responses/listPets"
  /pets/{petId}:
    get:
      summary: Info for a specific pet
      tags:
        - pets
      parameters:
        - name: petId
          in: path
          required: true
          description: The id of the pet to retrieve
          schema:
            type: string
      responses:
        '200':
          "$ref": "#/components/responses/getPet"

Swagger-UI configuration options:

  window.ui = SwaggerUIBundle({
    url: "http://url.com/swagger.json",
    dom_id: '#swagger-ui',
    deepLinking: true,
    presets: [
      SwaggerUIBundle.presets.apis,
      SwaggerUIStandalonePreset
    ],
    plugins: [
      SwaggerUIBundle.plugins.DownloadUrl
    ],
    layout: "StandaloneLayout"
  });

Describe the bug you're encountering

When the paths key is defined after the components key, the allOf $ref properties are not rendered properly

To reproduce...

Steps to reproduce the behavior:

  1. Go to 'swagger editor'
  2. Paste in example YAML
  3. Open /pets
  4. See that only the id field is visible

Expected behavior

All the fields of the $ref should be visible

Screenshots

image

Should be: image

Additional context or thoughts

This issue is also defined in #5194 and should be fixed in an older version, but seems to be broken (again)?

AleksanderZdunek commented 1 year ago

I have essentially the same issue but with Swagger 2.0 and destinations before paths.

Q&A (please complete the following information)

Content & configuration

Example Swagger definition:

basePath: /
definitions:
  A:
    allOf:
      - $ref: '#/definitions/B'
      - properties:
          a:
            type: integer
    type: object
  B:
    allOf:
      - $ref: '#/definitions/C'
      - properties:
          b:
            type: number
    type: object
  C:
    allOf:
      - $ref: '#/definitions/D'
      - properties:
          c:
            type: string
    type: object
  D:
    properties:
      d:
        type: boolean
    type: object
info:
  title: Test
  version: '1.0'
paths:
  /get:
    get:
      responses:
        '200':
          description: Successful response
          schema:
            $ref: '#/definitions/A'
      summary: Get things
swagger: '2.0'

Swagger-UI configuration options:

  window.ui = SwaggerUIBundle({
    url: "https://{my domain and path}/swagger_minimal.yaml",
    dom_id: '#swagger-ui',
    deepLinking: true,
    presets: [
      SwaggerUIBundle.presets.apis,
      SwaggerUIStandalonePreset
    ],
    plugins: [
      SwaggerUIBundle.plugins.DownloadUrl
    ],
    layout: "StandaloneLayout"
  });
https://{my domain and path}/swagger-ui-4.15.5/dist/#/default/get_get

Describe the bug you're encountering

When definitions appear before paths in our swagger schema, and several levels of nested allOf, not all properties are shown in the Path-Response-Model view.

To reproduce...

Steps to reproduce the behavior:

  1. Go to 'swagger editor'
  2. Paste in example YAML
  3. Expand /get and click Model
  4. Observe that only properties a and b are shown

Expected behavior

I expect to see properties a, b, c, d.

Screenshots

Screenshot 2022-12-06 at 15-06-32 Swagger Editor Should be: Screenshot 2022-12-06 at 15-45-52 Swagger Editor

Additional context or thoughts

When placing paths before definitions things appear correctly. I haven't found any explicit mention in the Swagger specification that fields shall appear in a certain order, so I think this is a bug in swagger-ui. My swagger generator produces the fields in random or lexicographical order depending on environment.

When skipping the C definition and letting B reference D directly, I see three properties as expected. So it seems to me that, at least with my example, swagger-ui can handle two levels of allOf but not three levels.

I have tried my example Swagger definition with swagger-ui versions 4.15.5, 4.0.0, 3.36.1, 3.36.0, and 3.24.3. With 3.36.1 and higher I see only properties a, b, as described above. With 3.36.0 and lower I see only properties c, d.