spring-bootswaggerspringdocjakarta-validation

Disable processing validation annotations in springdoc


I want to remove parameter "minimum" from autogenerated swagger documentation

I use the springdoc library to automatically generate swagger documentation

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.1.0</version>
</dependency>

I have this method in one of the controllers

@GetMapping("page")
@ResponseStatus(HttpStatus.OK)
List<RecordInfoDto> getPage(@RequestParam("size")
                            @jakarta.validation.constraints.Min(value = 1, message = "size must be more than 0") 
                            int size,
                            @RequestParam("number")
                            @jakarta.validation.constraints.Min(value = 0, message = "number must be non-negative")
                            int number);

The following documentation is generated for this method

"/page": {
    "get": {
    ...
        "parameters": [
          {
            "name": "size",
            "in": "query",
            "required": true,
            "schema": {
              "minimum": 1,
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "number",
            "in": "query",
            "required": true,
            "schema": {
              "minimum": 0,
              "type": "integer",
              "format": "int32"
            }
          }
        ],
     ...

I want the same swagger documentation, only without the "minimum" parameter in the "schema" section

I tried to explicitly specify scheme using the io.swagger.v3.oas.annotations.media.annotation.Scheme, but it didn't help, in whatever order I put the annotations

@GetMapping("page")
@ResponseStatus(HttpStatus.OK)
List<RecordInfoDto> getPage(@RequestParam("size")
                            @io.swagger.v3.oas.annotations.media.Schema(minimum = "100")
                            @jakarta.validation.constraints.Min(value = 1, message = "size must be more than 0")
                            int size,
                            @RequestParam("number")
                            @jakarta.validation.constraints.Min(value = 0, message = "number must be non-negative")
                            int number);

The documentation still had "minimum": 1 for parameter size

I tried using io.swagger.v3.oas.annotations.Parameter, but it didn't help either

@GetMapping("page")
@ResponseStatus(HttpStatus.OK)
List<RecordInfoDto> getPage(@RequestParam("size")
                            @io.swagger.v3.oas.annotations.Parameter(name = "size",
                                    required = true,
                                    in = ParameterIn.QUERY,
                                    schema = @Schema(minimum = "100"))
                            @jakarta.validation.constraints.Min(value = 1, message = "size must be more than 0")
                            int size,
                            @RequestParam("number")
                            @jakarta.validation.constraints.Min(value = 0, message = "number must be non-negative")
                            int number);

At the same time, if I remove the annotation jakarta.validation.constraints.Min, the documentation is generated according to the annotations and the minimum becomes 100


Solution

  • What you want is to make the Open API specification lie.

    As you said in the comment, you "don't want to remove the @Min annotation, because it is required for real validation", on other side you want to hide this validation constraint in the generated Open API specification.

    Your requirement is contradictory and you should not be surprised that it is not possible.

    The purpose of the documentation is to specify the contract of your API. If your API validates minimum value, it is a part of its contract. And the purpose of a machine readable documentation (Open API) is among other to automatically prevent the clients to send an invalid request.

    Having @Schema(minimum="100") and @Min(value=1) is schizophrenic.

    The validation is part of the contract and it should be in the Open API specification. If a part of the contract is that the minimum value is 1, you don't have to specify anything else. It is obvious (part of a more general contract of any web service) that the client will receive 400 and some meaningful error message. I never recommend to promise any exact error message in the contract.

    You may also add to the whole RestController class or to every single method something like this:

    @ApiResponse(responseCode = "400", 
        content = @Content(
            mediaType = MediaType.APPLICATION_JSON_VALUE, 
            schema = @Schema(implementation = MyError.class),
            examples = @ExampleObject(value = "{\"code\": \"INVALID_INPUT\", \"message\": \"Currency USD not supported\" }")
        )
    )
    @ApiResponse(responseCode = "403",
        content = @Content(
            mediaType = MediaType.APPLICATION_JSON_VALUE,
            schema = @Schema(implementation = MyError.class),
            examples = @ExampleObject(value = "{\"code\": \"FORBIDDEN\", \"message\": \"Forbidden access to something\" }")
        )
    )
    @ApiResponse(responseCode = "404", 
        content = @Content(
            mediaType = MediaType.APPLICATION_JSON_VALUE,
            schema = @Schema(implementation = MyError.class),
            examples = @ExampleObject(value = "{\"code\": \"RESOURCE_NOT_FOUND\", \"message\": \"User not found\" }")
        )
    )
    @ApiResponse(responseCode = "500",
        content = @Content(
            mediaType = MediaType.APPLICATION_JSON_VALUE, 
            schema = @Schema(implementation = MyError.class),
            examples = @ExampleObject(value = "{\"code\": \"EXTERNAL_API_CALL_ERROR\", \"message\": \"Central register API not available\" }")))