OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
21.35k stars 6.46k forks source link

[Java][Spring] Optional query parameter of type array-string doesn't respect defaults #890

Open jason-cohen opened 6 years ago

jason-cohen commented 6 years ago
Description

Using OAS 3, I have a query parameter defined as follows:

    exampleSort:
      name: sort
      description: Sort parameters for list response
      in: query
      required: false
      schema:
        type: array
        items:
          type: string
        default: 'a'

However after running the generator, my controller class has the following defined as defaultValue:

@ApiParam(value = "Sort parameters for list response", defaultValue = "new ArrayList<>()") @Valid @RequestParam(value = "sort", required = false, defaultValue="new ArrayList<>()") List<String> sort

When a request is made to the service with the optional parameter missing, Spring creates a new string list and adds new ArrayList<>() as the single element of the list, so the defaulted string becomes:

List<String> sort = ["new ArrayList<>()"]

When I leave required: false but remove the default entry:

    exampleSort:
      name: sort
      description: Sort parameters for list response
      in: query
      required: false
      schema:
        type: array
        items:
          type: string

Then the result is

@ApiParam(value = "Sort parameters for list response") @Valid @RequestParam(value = "sort", required = false) List<String> sort

But in this case, Spring does not create a default value (since none was specified), so sort becomes null in the controller:

List<String> sort = null

Spring MVC expects a String as default value, but if it's meant to be a list, it could be a comma delimited list as a string "a" or at the very least, an empty string (which is parsed as an empty list).

openapi-generator version

3.2.2

OpenAPI declaration file content or url
openapi: 3.0.0
paths:
  /v1/examples:
    get:
      tags:
        - Example
      summary: Get a list of Examples
      operationId: getExamples
      parameters:
        - $ref: '#/components/parameters/exampleSort'
...
components:
  parameters:
    exampleSort:
      name: sort
      description: Sort parameters for list response
      in: query
      required: false
      schema:
        type: array
        items:
          type: string
        default: 'a'
...
Command line used for generation

Gradle task

openApiGenerate {
    inputSpec = openApiInput.path
    outputDir = openApiOutputDir.path
    generatorName = 'spring'
    invokerPackage = ...
    modelPackage = ...
    apiPackage = ...
    additionalProperties = [
        'interfaceOnly'     : 'true',
        'basePackage'       : ...,
        'configPackage'     : ...,
        'sourceFolder'      : 'src/generated/java/',
        'java8'             : 'true',
        'delegatePattern'   : 'true',
        'implicitHeaders'   : 'true',
        'useTags'           : 'true',
        'booleanGetterPrefix': 'is',
    ]
}
Steps to reproduce

See description ^^

Related issues/PRs

None

Suggest a fix/enhancement

I've already deduced where this value is coming from:

AbstractJavaCodegen.toDefaultValue(Schema p) {...}

Perhaps a resolution could be to override toDefaultValue(Schema p) in SpringCodegen to implement the necessary functionality, without having to worry about the implications on other types of code generators.

jmini commented 6 years ago

Thank you for the detailed issue report.

Feel free to propose a pull request with the proposed change. Let us know if you need help.