openApi generator spring template omits default values of properties

734 Views Asked by At

I attach a basic OAS 3.0 schema below. When using editor.swagger.io, I am able to view the default values of my properties in generated page, when expanding the schema details.

openapi: 3.0.3
info:
  title: API Specification
  version: 1.0.0
servers:
  - url: https://localhost
paths:
  /operation:
    post:
      operationId: run
      requestBody:
        description: Description
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Request'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Response'
        '400':
          description: Bad request
        '500':
          description: Internal Server Error
components:
  schemas:
    Request:
      type: object
      properties:
        x:
          type: number
          example: 0
          default: 2
    Response:
      type: object
      properties:
        id:
          type: integer

enter image description here

However, when generating the server stubs with the spring engine from the top menu of the editor, I notice that the defaultValue property of the @Schema annotation is not populated.

  // ...
  @JsonProperty("x")
  private BigDecimal x = new BigDecimal(2);
  // ...
  /**
   * Get x
   * @return x
   **/
  @Schema(example = "0", description = "")
  
    @Valid
    public BigDecimal getX() {
    return x;
  }

As you can see, the generated server class correctly instantiates the default variable. It's really the property defaultValue of the @Schema annotation that I am missing. I've seen this property being included in @Parameter objects in OAS. What I would like to see in the above annotation is the additional property as below:

  @Schema(example = "0", description = "", defaultValue="2")

Is this a bug of the spring engine template?

I would like to avoid immediately resorting to a custom mustache template if my problem has a known solution with less maintenance.

2

There are 2 best solutions below

2
Manny On BEST ANSWER

I solved my use-case by bypassing the automatically generated springdoc-openapi file, and directly serving my own original yaml specification. My input specification file includes all the keywords I need, and they are properly rendered by springdoc's underlying swagger2 implementation.

Bonus: I also found out that with the above bypass, I am able to render markdown inside the operation block (the default green colored block of each operation). Sounds corny, but this was liberating and bothered me for a while.

To serve my own yaml, while also having the Try-it-Out button working without throwing those pesky CORS errors, I did the following:

  1. Placed my api.yaml file inside the resources/static folder
  2. Added the following server property in my application.properties.yaml
server:
  forward-headers-strategy: framework
  1. Modified some springdoc.swagger-ui properties as follows
springdoc:
  swagger-ui:
    enable: false
    useUnsafeMarkdown: true
    url: api.yaml
    path: /
    disable-swagger-default-url: true
  api-docs:
    enabled: false
    path: /api.yaml
    version: OPENAPI_3_0
  1. Added the following code in one of my @Configuration annotated classes. Note the use of @Primary, which ensures that these beans will be prioritized over other internal beans that do the same. Try to experiment without the annotation, and if it works for you, don't bother adding it. This is what worked for me!
    @Bean
    @Primary
    SpringDocConfiguration springDocConfiguration(){
       return new SpringDocConfiguration();
    }

    @Bean
    @Primary
    SpringDocConfigProperties springDocConfigProperties() {
       return new SpringDocConfigProperties();
    }

    @Bean
    @Primary
    ObjectMapperProvider objectMapperProvider(SpringDocConfigProperties springDocConfigProperties){

        return new ObjectMapperProvider(springDocConfigProperties);
    }

    @Bean
    @Primary
    SpringDocUIConfiguration SpringDocUIConfiguration(Optional<SwaggerUiConfigProperties> optionalSwaggerUiConfigProperties){

        return new SpringDocUIConfiguration(optionalSwaggerUiConfigProperties);
    }

  1. In your yaml specification, set the server url to "/". This may throw a warning by openapi-generator or springdoc, but it actually enabled the proper function of Try-It-Out button, which did not work for me, when serving the api page from the same port as the application. I have no authentication or actuator setup, so this may differ.

PS. I relied on the springdoc documentation FAQ 13.57 here, with some of my own settings to get it to work. I hope it helps someone!

4
Maksim Eliseev On

A little investigation on this question

Actually you have 2 problems in the generated sources:

  1. The @Parameter annotation in the generated interface wasn't generated quite correctly:

    ResponseEntity<Response> run(@Parameter(in = ParameterIn.DEFAULT, description = "Description", required=true, schema=@Schema()) @Valid @RequestBody Request body);
    

    As you can see, the schema parameter set incorrectly.

  2. The @Schema annotation in the generated Request class, as you described, doesn't have the defaultValue parameter:

    @Schema(example = "0", description = "")
    @Valid
    public BigDecimal getX() {
        return x;
    }
    

I tried the org.openapi.generator Gradle plugin (analogue of swagger codegen) and the result was the same:

  1. The schema parameter in the @Parameter annotation wasn't set:

    default ResponseEntity<Response> run(
          @Parameter(name = "Request", description = "Description", required = true) @Valid @RequestBody Request request
    ) {
        // ...
    }
    
  2. The same behaviour.


In general, the code of the Request class is generated correctly: the x field is initialized to the default value.

public class Request   {
    @JsonProperty("x")
    private BigDecimal x = new BigDecimal(2);

    // ...
}

Do you really need proper annotations?