Skip to content

Cannot override servers in api-docs.yaml using OpenApiCustomiser #1188

Closed
@bfrggit

Description

@bfrggit

Describe the bug

I cannot override the servers field in api-docs.yaml using a OpenApiCustomiser @Bean, while other fields like info.version seem to work well with this approach, the servers remains the auto generated value.

To Reproduce

Spring Boot 2.4.5

'org.springdoc:springdoc-openapi-ui:1.5.9'

I have a class in src/main annotated with @OpenAPIDefinition, servers parameter is not set in this annotation. I cannot paste all the codes here, but it is basically like this:

@Configuration
@OpenAPIDefinition(info = @Info(title = "...", version = "v0",
      description = "...",
      contact = @Contact( ... ),
      license = @License( ... )), //
      tags = { ... } //
)
public class OpenApiConfig {
   private static Parameter getHeaderTenantId() {
      return new Parameter().in(ParameterIn.HEADER.toString()).name("X-Tenant-ID").schema(new StringSchema())
            .required(true).description("Tenant ID to which the composer or other objects belong to.");
   }

   @Bean
   OpenApiCustomiser getDefaultOpenApiCustomiser() {
      return openApi -> openApi.getComponents().addParameters("TenantId", getHeaderTenantId());
   }
}

In my integration test, there is such a config class:

@Slf4j
@Configuration
public class OpenApiTestConfig {
   @Bean
   OpenApiCustomiser intTestOpenApiCustomiser() {
      // this is only added for integration tests
      // so the automatically generated OpenAPI documents do not have a `localhost` server URL with random port
      return openApi -> {
         log.info("intTestOpenApiCustomiser");
         openApi.getInfo().version("v1"); // this works, successfully overriding the value in `api-docs.yaml`
         openApi.servers(List.of(new Server().url("").description("My URL"))); // however, this does not
      };
   }
}

In the generated YAML file, version is "v1" but servers:

servers:
- url: http://localhost:46407/api
  description: Generated server url

Expected behavior

servers:
- url: ""
  description: My URL

Screenshots

No.

Additional context

The main codes will serve the Swagger UI, documentation, etc. at runtime so I do not want to mess up with its own config. However, during the integration test, I'd like to "download" the YAML file so I can publish it somewhere using the build pipeline. I do not want this file to contain the random port server URL in the integration test.

So far as I am aware of, there are 3 ways that I can set this servers field in the YAML file:

  1. In @OpenAPIDefinition.
  2. In @Bean OpenAPI.
  3. In @Bean OpenApiCustomiser.

And I have two different source sets (main and integration tests). I want my application to use the generated URL when serving the Swagger UI, but let it use a fixed, hard-coded server URL in the YAML file when running integration tests so I can "download" the YAML file that does not contain a random server URL.

Other things I tried:

  1. Creating a @Bean OpenAPI in the main config class, instead of using @OpenAPIDefinition, then use the same customizers (in both main and integration tests). This does NOT work.
  2. Setting everything (incl. info, tags, servers, etc.) in a single @Bean OpenAPI in the integration test config class (i.e., without using any customizer). This works as expected. However, this requires me to use two different @Bean OpenAPI, one in main and one in integration tests, which can cause some additional confusions.
  3. Setting servers in the main @OpenAPIDefinition to contain one Server, then the customizer in integration tests works as expected (i.e., it can override the settings I put in @OpenApiDefinition). However, just an experiment: This makes the server URL hardcoded. Even if I set servers to List.of() (empty list) later in a customizer, there is no generated URL in the YAML file.

Some of my guesses, no need to take it serious -- It seems that at some point

  • After @Bean OpenAPI or @OpenAPIDefinition (whichever is used) takes effect,
  • Before @Bean OpenApiCustomiser customisers take effect,

It tries to detect if servers is empty -- if it is not, then it is serving the YAML file containing the servers. However, if it is empty, it is serving the YAML file with servers set to the generated URL, IGNORING servers in the OpenAPI object permanently, which makes it impossible to change the behavior by modifying OpenAPI.servers later in the customisers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions