Skip to content

OpenApiCustomizer overridden by OperationIdCustomizer when both are defined #3035

Open
@johnycho

Description

@johnycho

Describe the bug

When I define a custom OpenApiCustomizer to customize the OpenAPI metadata (info, servers) using external properties, the values set in the customizer are not reflected in the final OpenAPI output.
I confirmed that the OpenApiCustomizer is invoked, but its settings appear to be overwritten — possibly by OperationIdCustomizer or another internal component.


To Reproduce

  • Spring Boot version: 3.5.2

  • springdoc-openapi version:

    implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.9'
  • application.yml

    springdoc:
      custom:
        title: joy admin api
        version: v1.0.1
        servers:
          - url: http://localhost:8081
            description: local
  • Spring Configuration:

    @Configuration
    @EnableConfigurationProperties(SpringDocProperties.class)
    @RequiredArgsConstructor
    public class SpringDocConfig {
    
      private final SpringDocProperties springDocProperties;
    
      @Bean
      OpenApiCustomizer commonOpenApiCustomizer() {
        return openApi -> openApi.servers(servers())
                                 .info(info());
      }
    
      private List<Server> servers() {
        return springDocProperties.getServers()
                                  .stream()
                                  .map(s -> new Server().url(s.getUrl()).description(s.getDescription()))
                                  .toList();
      }
    
      private Info info() {
        return new Info()
            .title(springDocProperties.getTitle())
            .version(springDocProperties.getVersion());
      }
    }
  • Property Binding Class:

    @Configuration
    @ConfigurationProperties("springdoc.custom")
    @Data
    public class SpringDocProperties {
    
      private String title = "API";
      private String version = "v0.0.1";
      private List<ServerInfo> servers = List.of();
    
      @Data
      public static class ServerInfo {
        private String url;
        private String description;
      }
    }
  • Actual Behavior:

    When accessing http://localhost:8081/v3/api-docs/springdocDefault, the OpenAPI spec still shows:

    {
      "info": {
        "title": "OpenAPI definition",
        "version": "v0"
      }
    }

    Even though OpenApiCustomizer should set it to:

    {
      "title": "joy admin api",
      "version": "v1.0.1"
    }
  • Expected Behavior:

    The customizer should override the OpenAPI.info() and OpenAPI.servers() sections. However, the current behavior suggests that these values are reset later in the pipeline.

  • Workaround:

    If I define a full @Bean OpenAPI customOpenAPI(), it works as expected:

    @Bean
    public OpenAPI customOpenAPI() {
      return new OpenAPI()
          .info(new Info().title(springDocProperties.getTitle()).version(springDocProperties.getVersion()));
    }

    But this defeats the purpose of using OpenApiCustomizer.


Screenshots

Not applicable — reproducible via JSON inspection at /v3/api-docs.


Additional context

This might be related to OperationIdCustomizer or another internal component that applies a new OpenAPI.info() object, thereby discarding the result from the customizer.

Would be helpful to clarify precedence between customizers and internal configurations — or provide a way to prevent overwriting custom OpenApiCustomizer behavior.

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