swagger-api / swagger-parser

Swagger Spec to Java POJOs
http://swagger.io
Apache License 2.0
773 stars 525 forks source link

Unable to Parse Referenced ArraySchema in Swagger File #2065

Open rialkush opened 3 months ago

rialkush commented 3 months ago

Description: The current swagger-parser (version 2.1.21) fails to parse the referenced ArraySchema in the provided Swagger YAML file. When attempting to resolve the schema, the parser returns a null value for $ref and ignores the object properties defined within the array schema, which leads to incomplete parsing. It captures addresses field as ArraySchema but failed to capture it's properties.

Steps to Reproduce:

Expected Behavior: The Swagger parser should successfully parse and resolve all referenced schemas, including ArraySchema, providing complete and accurate schema definitions.

YAML File:

openapi: 3.0.0
info:
  title: Sample API
  version: 1.0.0
paths:
  /users:
    post:
      summary: Create a new user
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserInput'
      responses:
        '201':
          description: Created

components:
  schemas:
    UserInput:
      type: object
      properties:
        username:
          type: string
        addresses:
          type: array
          items:
            $ref: '#/components/schemas/Address'
    Address:
      type: object
      properties:
        street:
          type: string
        city:
          type: string
        zip:
          type: string

Dependency used:

<dependency>
      <groupId>io.swagger.parser.v3</groupId>
      <artifactId>swagger-parser</artifactId>
      <version>2.1.21</version>
  </dependency>

Swagger parser configurations:

  OpenAPIV3Parser parser = new OpenAPIV3Parser();
    ParseOptions options = new ParseOptions();
    options.setResolve(true);
    options.setResolveFully(true);
    options.setResolveRequestBody(true);
    options.setResolveCombinators(true);
    io.swagger.v3.oas.models.OpenAPI swagger = parser.read("api-specification/sample-api.yaml", null, options);
    Map<String, PathItem> paths = swagger.getPaths();
    System.out.println(paths);

Output (with unresolved ArraySchema):

 class Paths {
    {/users=class PathItem {
        summary: null
        description: null
        get: null
        put: null
        post: class Operation {
            tags: null
            summary: Create a new user
            description: null
            externalDocs: null
            operationId: null
            parameters: null
            requestBody: class RequestBody {
                description: null
                content: class Content {
                    {application/json=class MediaType {
                        schema: class ObjectSchema {
                            class Schema {
                                type: object
                                format: null
                                $ref: null
                                description: null
                                title: null
                                multipleOf: null
                                maximum: null
                                exclusiveMaximum: null
                                minimum: null
                                exclusiveMinimum: null
                                maxLength: null
                                minLength: null
                                pattern: null
                                maxItems: null
                                minItems: null
                                uniqueItems: null
                                maxProperties: null
                                minProperties: null
                                required: null
                                not: null
                                properties: {username=class StringSchema {
                                    class Schema {
                                        type: string
                                        format: null
                                        $ref: null
                                        description: null
                                        title: null
                                        multipleOf: null
                                        maximum: null
                                        exclusiveMaximum: null
                                        minimum: null
                                        exclusiveMinimum: null
                                        maxLength: null
                                        minLength: null
                                        pattern: null
                                        maxItems: null
                                        minItems: null
                                        uniqueItems: null
                                        maxProperties: null
                                        minProperties: null
                                        required: null
                                        not: null
                                        properties: null
                                        additionalProperties: null
                                        nullable: null
                                        readOnly: null
                                        writeOnly: null
                                        example: null
                                        externalDocs: null
                                        deprecated: null
                                        discriminator: null
                                        xml: null
                                    }
                                }, addresses=class ArraySchema {
                                    class Schema {
                                        type: array
                                        format: null
                                        $ref: null
                                        description: null
                                        title: null
                                        multipleOf: null
                                        maximum: null
                                        exclusiveMaximum: null
                                        minimum: null
                                        exclusiveMinimum: null
                                        maxLength: null
                                        minLength: null
                                        pattern: null
                                        maxItems: null
                                        minItems: null
                                        uniqueItems: null
                                        maxProperties: null
                                        minProperties: null
                                        required: null
                                        not: null
                                        properties: null
                                        additionalProperties: null
                                        nullable: null
                                        readOnly: null
                                        writeOnly: null
                                        example: null
                                        externalDocs: null
                                        deprecated: null
                                        discriminator: null
                                        xml: null
                                    }
                                }}
                                additionalProperties: null
                                nullable: null
                                readOnly: null
                                writeOnly: null
                                example: null
                                externalDocs: null
                                deprecated: null
                                discriminator: null
                                xml: null
                            }
                        }
                        examples: null
                        example: null
                        encoding: null
                    }}
                }
                required: true
            }
            responses: class ApiResponses {
                {201=class ApiResponse {
                    description: Created
                    headers: null
                    content: null
                    links: null
                    extensions: null
                    $ref: null
                }}
                extensions: null
            }
            callbacks: null
            deprecated: null
            security: null
            servers: null
        }
        delete: null
        options: null
        head: null
        patch: null
        trace: null
        servers: null
        parameters: null
        $ref: null
    }}
}
kmittig commented 3 months ago

Same problem here. It may be fine, that $ref is null inside ArraySchema, because the $ref belongs to the items, but the items inside won’t get parsed and are missing in the output.