Description
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:
- In
@OpenAPIDefinition
. - In
@Bean OpenAPI
. - 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:
- Creating a
@Bean OpenAPI
in themain
config class, instead of using@OpenAPIDefinition
, then use the same customizers (in bothmain
and integration tests). This does NOT work. - 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 inmain
and one in integration tests, which can cause some additional confusions. - Setting
servers
in the main@OpenAPIDefinition
to contain oneServer
, 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 setservers
toList.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.