Skip to content

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

Open
@jsilland

Description

@jsilland
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}}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions