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

Parameters with the same name but different locations are incorrectly returned when using JSON references ($ref) with openapi 3.0.x. #2102

Open
AdrianVasiliu opened this issue May 16, 2024 · 0 comments

Comments

@AdrianVasiliu
Copy link

AdrianVasiliu commented May 16, 2024

Multiple parameters with the same name but different locations (for instance, in: query vs in: header) are wrongly handled by the parser if:

  • the parameters are described using JSON references ($ref).
  • and the OpenAPI file declares its version as v3.0.x ("openapi": "3.0.0" or "openapi": "3.0.3").

The issue does NOT occur when either not using $ref, or declaring "openapi": "3.1.0".

This looks like a bug because:

a) It violates the OpenAPI spec (both v3.0 and v3.1):

A unique parameter is defined by a combination of a name and location.

https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md#parameter-object

This should be respected regardless of whether the parameter is defined with, or without $ref.

b) I don't see a mention of a change in this area between v3.0 and v3.1 (for instance here or here) which would justify the difference of behaviour.


How to reproduce (holds at least for swagger-parser 2.1.22 and 2.1.19):

package parsertest;

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.parser.OpenAPIV3Parser;
import io.swagger.v3.parser.core.models.ParseOptions;

import java.io.IOException;
import java.util.List;

public class ParserTest {
    public static void main(String[] args) throws IOException {
        test("src/test/resources/parsertest/openapi-ok.json");
        test("src/test/resources/jparsertest/openapi-ko.json");
    }
    
    private static void test(String openapiFile) throws IOException {
        System.out.println("=== OpenAPI file:" + openapiFile);
        final ParseOptions options = new ParseOptions();
        options.setResolve(true);
        options.setResolveCombinators(true);
        options.setResolveFully(true);
        
        final OpenAPI openAPI = new OpenAPIV3Parser().read(openapiFile, null, options);
        
        final List<Parameter> parameters = openAPI.getPaths().get("/myoperation").getGet().getParameters();
        parameters.forEach(parameter -> {
            if (parameter != null) {
                System.out.println("Parameter name: " + parameter.getName() + " in: " + parameter.getIn());
            }
        });
    }
}

openapi-ko.json:

{
  "openapi": "3.0.0",
  "paths": {
    "/myoperation": {
      "get": {
        "parameters": [
          {"$ref": "#/components/parameters/schemaParam1"},
          {"$ref": "#/components/parameters/schemaParam2"}
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
  }}}}}}},
  "components": {
    "parameters": {
      "schemaParam1": {
        "name": "myParam",
        "in": "query",
        "schema": {
          "type": "string"
        }
      },
      "schemaParam2": {
        "name": "myParam",
        "in": "header",
        "schema": {
          "type": "string"
        }
   }}}
}

openapi-ok.json:

{
  "openapi": "3.0.0",
  "paths": {
    "/myoperation": {
      "get": {
        "parameters": [
          {
            "in": "query",
            "name": "myParam",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "myParam",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
  }}}}}}}
}

Output:

=== OpenAPI file:src/test/resources/parsertest/openapi-ok.json
Parameter name: myParam in: query
Parameter name: myParam in: header
=== OpenAPI file:src/test/resources/parsertest/openapi-ko.json
Parameter name: myParam in: query

That is, for the OpenAPI using $ref, only one of the two parameters is returned by getParameters().

For comparison, if modifying the OpenAPI files to declare "openapi": 3.1.0, both the header and query parameter are returned:

=== OpenAPI file:src/test/resources/parsertest/openapi-ok.json
Parameter name: myParam in: query
Parameter name: myParam in: header
=== OpenAPI file:src/test/resources/parsertest/openapi-ko.json
Parameter name: myParam in: query
Parameter name: myParam in: header
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant