Search code examples
springspring-bootswaggeropenapispringdoc

Using @Schema annotation for Open Api v3


I'm trying to change Swagger2 to OpenApi3, first thing I made is changing annotations @ApiModel and @ApiModelProperty to @Schema. I use 'swagger-message.properties' file because I need to keep my cyrillic symbols there. Here is my settings beans:

public OpenAPI customOpenAPI(BuildProperties buildProperties) {
    return new OpenAPI()
        .info(new Info()
        .title("bundle-ws")
        .version(buildProperties.getVersion())
        .description("Bundle Ws"));
}

@Bean
public GroupedOpenApi bundleApi() {
    return buildGroupedOpenApi("Bundle", "/bundle/**");
}

@Bean
public TranslationOperationCustomizer translationOperationCustomizer() {
    return new TranslationOperationCustomizer();
}

@Bean
public TranslationSchemaCustomizer translationSchemaCustomizer() {
   return new TranslationSchemaCustomizer();
}

private GroupedOpenApi buildGroupedOpenApi(String group, String... pathsToMatch) {
    return GroupedOpenApi.builder().group(group)
        .pathsToMatch(pathsToMatch)
        .addOperationCustomizer(translationOperationCustomizer())
        .build();
}

@Bean
public ResourceBundleMessageSource translator() {
    ResourceBundleMessageSource source = new ResourceBundleMessageSource();
    source.setBasenames("swagger-message");
    source.setUseCodeAsDefaultMessage(true);
    source.setDefaultEncoding("utf-8");
    return source;
}

public static class TranslationOperationCustomizer implements OperationCustomizer {

    @Autowired
    protected MessageSource translator;

    @Override
    public Operation customize(Operation operation, HandlerMethod handlerMethod) {
        operation.setSummary(translate(operation.getSummary()));
        operation.getResponses().values().forEach(apiResponse -> apiResponse.setDescription(translate(apiResponse.getDescription())));
        return operation;
    }

    private String translate(String message) {
        return translator.getMessage(message, null, message, Locale.getDefault());
    }
}

public static class TranslationSchemaCustomizer implements PropertyCustomizer {

    @Autowired
    protected MessageSource translator;

    @Override
    public Schema customize(Schema property, AnnotatedType type) {
        property.setDescription(translate(property.getDescription()));
        return property;
    }

    private String translate(String message) {
        return translator.getMessage(message, null, message, Locale.getDefault());
    }
}

Here is my class I want to be shown in the SwaggerUI:

@Schema(description = "ErrorResponse")
@Data
public class ErrorResponse {

    @Schema(description = "ErrorCode", required = true)
    private final Integer errorCode;

    @Schema(description = "ErrorMessage")
    private final String errorMessage;
}

ErrorResponse, ErrorCode, and ErrorMessage are params of my properties file:

ErrorResponse=Результат обработки запроса при неуспешном ответе
ErrorCode=Код ошибки
ErrorMessage=Сообщение об ошибке

But the fields can be read by Swagger, while the annotation on the class isn't read: enter image description here

How to make in shown the description of the class like the descriptions of the fields?


Solution

  • You have to use description = "${ErrorResponse}" (add $) and set springdoc.api-docs.resolve-schema-properties to true.

    source: https://springdoc.org/faq.html