How to have the real application-produced response schema in springdoc-openapi?

106 Views Asked by At

I have a Spring Boot project using springdoc-openapi-starter-webmvc-ui to create an openapi-specification and show a Swagger UI. The project also uses Jackson to serialize data in JSON format. Jackson is configured to understand the java.time types and serialize them as strings (see the @Bean ObjectMapper configuration below). However, when running the project and looking at the Swagger UI, the openapi-calculcated response schema differs from the real serialization. See in the following two code snippets the difference in test2 field, which is of type java.time.YearMonth. Also note that the schema calculation for test1 field works, which is of type java.time.Instant.

Actual response:

{
  "test1": "2023-11-06T10:53:42.781130500Z",
  "test2": "2023-11"
}

Response schema by openapi:

{
  "test1": "2023-11-06T10:53:42.788Z",
  "test2": {
    "year": 0,
    "month": "JANUARY",
    "monthValue": 0,
    "leapYear": true
  }
}

This is the Controller:

@RestController
public class TestController {
    @GetMapping("/test")
    public TestDto testDto() {
        TestDto testDto = new TestDto();
        testDto.setTest1(Instant.now());
        testDto.setTest2(YearMonth.now());
        return testDto;
    }
}

This is the model class:

@Data
public class TestDto {
    private Instant test1;
    private YearMonth test2;
}

And the ObjectMapper configuration:

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JavaTimeModule());
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        return objectMapper;
    }

I know that I could do the following:

@Data
public class TestDto {
    private Instant test1;
    @Schema(type = "string", format = "yearmonth", example = "2020-07")
    private YearMonth test2;
}

This would work: in the openapi-specification, the schema will be like this:

{
  "test1": "2023-11-06T11:13:56.750Z",
  "test2": "2020-07"
}

Which is exactly what I want. However, I do not want to add this @Schema annotation manually, because this might affect multiple fields in multiple classes. I want the openapi-specification to have the exact response schema that is produced by my application. How can I achieve this?

Here is a MWE: https://github.com/SebastianOltmanns/springdoc-jackson

0

There are 0 best solutions below