swagger-api / swagger-api/swagger-codegen

[JAVA] Retrofit2 client doesn't support path parameters that are collections

Open
#6,504 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Mustache
Stars
17.8k
Forks
6k
PR merge metrics
No merged PRs in 30d

Description

Description

When declaring a path parameter that is an array with a collectionFormat of csv, the Retrofit2 code generator declares the parameter as a List rather than a CSVParams. When Retrofit generates the URL for the API call, the parameter is incorrectly serialized as [foo,%20bar], which is the result of calling toString on the list.

This is admittedly a very much of an edge case but we're trying to retrofit an OpenAPI specification over an API that has existed for years and which makes use of this. We could probably work around this issue by tweaking the endpoint of the API on the server side but this is something I would rather avoid having to do. If the OpenApi specification allows for such parameters to be declared, code generators should support them.

Swagger-codegen version

2.2.3

Swagger declaration file content or url

This is the declaration of the endpoint — some parts omitted for brevity

    "/activities/{id}/streams/{stream_types}": {
      "get": {
        "operationId": "getActivityStreams",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "type": "integer"
          },
          {
            "name": "stream_types",
            "in": "path",
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "time",
                "distance",
                "latlng"
              ]
            },
            "collectionFormat": "csv",
            "minItems": 1
          }
        ]
      }
    }
Command line used for generation

swagger-codegen generate -i myspec.json -c config.json -l java -o java

The relevant parts of the config are:

{
  "useRxJava2": true,
  "library": "retrofit2"
}
Steps to reproduce
  • Declare an endpoint with a parameter that is an array with a collectionFormat
  • Configure the java generator to use the retrofit2 templates
  • Run the generator against the spec and the configuration

This is the generated code

@GET("activities/{id}/streams/{stream_types}")
  Observable<StreamSet> getActivityStreams(
    @retrofit2.http.Path("id") Integer id, @retrofit2.http.Path("stream_types") List<String> streamTypes
  );
Related issues/PRs

None found

Suggest a fix/enhancement

For query parameters, the template to generate query parameters (modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/queryParams.mustache) special-cases collections:

{{#isQueryParam}}@retrofit2.http.Query("{{baseName}}") {{#collectionFormat}}{{#isCollectionFormatMulti}}{{{dataType}}}{{/isCollectionFormatMulti}}{{^isCollectionFormatMulti}}{{{collectionFormat.toUpperCase}}}Params{{/isCollectionFormatMulti}}{{/collectionFormat}}{{^collectionFormat}}{{{dataType}}}{{/collectionFormat}} {{paramName}}{{/isQueryParam}}

But the same is not true for path parameters — the template (modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/pathParams.mustache) is much simpler:

{{#isPathParam}}@retrofit2.http.Path("{{baseName}}") {{{dataType}}} {{paramName}}{{/isPathParam}}

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 modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/pathParams.mustache and compare it with queryParams.mustache, which already special-cases collection formats. Reproduce the Java Retrofit2 generation using the supplied OpenAPI declaration and configuration. Done means a CSV path collection is generated with the appropriate CSVParams type and is serialized correctly instead of using List.toString().

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
api, tooling
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.