Skip to content

v3.0.3 renders defaultValue: "" although @Schema does not mention it #3285

@sebsprenger

Description

@sebsprenger

Describe the bug

We updated from "org.springdoc:springdoc-openapi-starter-webmvc-ui:3.0.2" to "org.springdoc:springdoc-openapi-starter-webmvc-ui:3.0.3" and since then noticed, that code like this

    @Getter
    @Accessors(fluent = true)
    @AllArgsConstructor
    public static class Amount {
        @Schema(description = "amount in smallest unit of its currency, e.g. cent", requiredMode = REQUIRED)
        @JsonProperty("value")
        private Integer value;

        @Schema(description = "ISO Standard, e.g. 'EUR'", requiredMode = REQUIRED)
        @JsonProperty("currency")
        private String currency;
    }

is being rendered to

components:
  schemas:
    Amount:
      type: object
      properties:
        currency:
          type: string
          default: ""
          description: "ISO Standard, e.g. 'EUR'"
        value:
          type: integer
          format: int32
          default: ""
          description: "amount in smallest unit of its currency, e.g. cent"

The default: "" is new. It does not make any sense for an integer to have a default value of empty string. In other cases we added validation annotation like @NotBlank which effectively adds an minLength: 1 to the OpenAPI spec - there a default: "" is also not valid.

To Reproduce
Steps to reproduce the behavior:

  • Using "org.springframework.boot:spring-boot-starter-webmvc:4.0.6"
  • Using "org.springdoc:springdoc-openapi-starter-webmvc-ui:3.0.3"
  • Using "io.swagger.core.v3:swagger-annotations:2.2.49"
  • Working with yaml

Code example:

package com.example;

import io.swagger.v3.oas.annotations.media.Schema;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SpringDocDefaultValueController {

    @GetMapping("/defaultValueDemo")
    ResponseEntity<TestResponse> endpoint() {
        var response = new TestResponse(true, 42, Currency.EUR, "hello world");
        return ResponseEntity.ok(response);
    }

    private record TestResponse(
            @Schema(description = "a bool")
            boolean myBool,
            @Schema(description = "an int")
            int myInt,
            @Schema(description = "an enum")
            Currency myEnum,
            @Schema(description = "a string")
            String myString) {}

    private enum Currency {EUR, USD}
}

v3.0.3 renders into

openapi: 3.1.0
info:
  description: test
  title: test
  version: 1.0.0
servers:
- description: test
  url: https://example.com
paths:
  /defaultValueDemo:
    get:
      operationId: endpoint
      responses:
        "200":
          content:
            '*/*':
              schema:
                $ref: "#/components/schemas/TestResponse"
          description: OK
      tags:
      - spring-doc-default-value-controller
components:
  schemas:
    TestResponse:
      type: object
      properties:
        myBool:
          type: boolean
          default: false
          description: a bool
        myEnum:
          type: string
          default: ""
          description: an enum
          enum:
          - EUR
          - USD
        myInt:
          type: integer
          format: int32
          default: ""
          description: an int
        myString:
          type: string
          default: ""
          description: a string

Expected behavior

We expect the default values not to be there at all, since we did not specify them in the @Schema annotation. Furthermore, we expect default values to at least have the correct type. Empty string is not a valid fit for an integer.
v3.0.2 renders into the following yaml, which we consider "more correct".

openapi: 3.1.0
info:
  description: test
  title: test
  version: 1.0.0
servers:
- description: test
  url: https://example.com
paths:
  /defaultValueDemo:
    get:
      operationId: endpoint
      responses:
        "200":
          content:
            '*/*':
              schema:
                $ref: "#/components/schemas/TestResponse"
          description: OK
      tags:
      - spring-doc-default-value-controller
components:
  schemas:
    TestResponse:
      type: object
      properties:
        myBool:
          type: boolean
          description: a bool
        myEnum:
          type: string
          description: an enum
          enum:
          - EUR
          - USD
        myInt:
          type: integer
          format: int32
          description: an int
        myString:
          type: string
          description: a string

Additional context
Problems were initially exposed by https://hub.docker.com/r/p1c2u/openapi-spec-validator in our pipeline.

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