swagger-api / swagger-api/swagger-parser

Swagger spec deserialization inconsistencies

Open
#965 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
867
Forks
560
Avg merge
2d 21h
Merged PRs (30d)
7

Description

Hi, I'm refactoring my Swagger 2.0 spec into a few common files for ease of maintenance. However, the tooling I use to build my clients and models is using some outdated versions of the io.swagger packages so the remote file references aren't working so I'm using a small maven plugin to serialize/parse the spec files and deserialize it back to a file for consumption by the upstream tooling. Here is an excerpt of the spec:

paths:
  /users/{userId}:
    get:
      parameters:
        - $ref: '#/parameters/UserIdPathParam'
parameters:
  UserIdPathParam:
    $ref: './parameters.yaml#/parameters/UserIdPathParam'
  UserChannelIdPathParam:
    $ref: './parameters.yaml#/parameters/UserChannelIdPathParam'
definitions:
  Message:
    $ref: './definitions.yaml#/definitions/Message'
  ErrorResponse:
    $ref: './definitions.yaml#/definitions/ErrorResponse'

I'm reading this spec with swagger-parser 1.0.40:

final SwaggerDeserializationResult sdr = new SwaggerParser()
                .readWithInfo(inputYaml, null, true);
sdr.getMessages().forEach(m -> LOG.info("Message: {}.", m));
final Swagger swaggerModel = sdr.getSwagger();

And then deserializing using the Yaml.mapper() jackson ObjectMapper.

What I'm noticing is that for definitions: it plugs in the values the SwaggerParser discovered in the remote file reference. However for parameters, it leaves the remove file references as is and instead it actually resolves the local references to them under paths:

paths:
  /users/{userId}:
    get:
      parameters:
      - name: "userId"
        in: "path"
        description: "User id path parameter"
        required: true
        type: "string"
parameters:
  UserIdPathParam:
    $ref: './parameters.yaml#/parameters/UserIdPathParam'
  UserChannelIdPathParam:
    $ref: './parameters.yaml#/parameters/UserChannelIdPathParam'
definitions:
  Message:
    type: "object"
    properties:
      message:
        type: "string"
        example: "Hello World"
        description: "The original message"
  ErrorResponse:
    type: "object"
    required:
    - "code"
    - "message"
    properties:
      code:
        type: "integer"
        format: "int32"
        example: 500
        description: "The HTTP error status code"
      message:
        type: "string"
        example: "The server encountered an error"
        description: "The reason for the error"
      fields:
        type: "array"
        example:
        - "Email is a required field"
        description: "An array of strings for specific reasons for the error"
        items:
          type: "string"

Is there a way to have parameters to behave like definitions?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the SwaggerParser.readWithInfo call and the Yaml.mapper() deserialization shown in the issue. Compare how referenced definitions and parameters are handled in the parsed model, then verify that parameter references are serialized consistently with definitions; done means the resulting YAML preserves the intended remote references or resolves both categories consistently.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, openapi
Domain
api
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.