
OpenApi 3 custom setup in Spring Boot using springdoc-openapi-ui
So I was migrating over our Spring Boot REST API project from Swagger 2 to OpenApi 3. So far it’s been pretty painless. I found a helper library called springdoc-openapi-ui that is for OpenApi 3 what SwaggerFox is for Swagger 2. That said, there are a few changes to the default setup we needed to support:
- Keycloak OAuth2 authentication
- API key authenication
- A
Version:
header enabled for every API endpoint
I clearly didn’t want to have to add the Version:
header manually to every endpoint manually. I found the following solution that does what I need it to do:
@Configuration
public class OpenApi3Config {
private BuildProperties buildProperties;
private String authServer;
private String realm;
@Autowired
public OpenApi3Config(BuildProperties buildProperties,
@Value("${keycloak.auth-server-url}") String authServer,
@Value("${keycloak.realm}") String realm) {
this.buildProperties = buildProperties;
this.authServer = authServer;
this.realm = realm;
}
@Bean
public OpenAPI openAPI() {
var authUrl = String.format("%s/realms/%s/protocol/openid-connect", this.authServer, this.realm);
return new OpenAPI()
.components(new Components()
.addSecuritySchemes("spring_oauth", new SecurityScheme()
.type(SecurityScheme.Type.OAUTH2)
.description("Oauth2 flow")
.flows(new OAuthFlows()
.authorizationCode(new OAuthFlow()
.authorizationUrl(authUrl + "/auth")
.refreshUrl(authUrl + "/token")
.tokenUrl(authUrl + "/token")
.scopes(new Scopes())
)))
.addSecuritySchemes("api_key", new SecurityScheme()
.type(SecurityScheme.Type.APIKEY)
.description("Api Key access")
.in(SecurityScheme.In.HEADER)
.name("API-KEY")
)
.addParameters("Version", new Parameter()
.in("header")
.name("Version")
.schema(new StringSchema())
.required(false)))
.security(Arrays.asList(
new SecurityRequirement().addList("spring_oauth"),
new SecurityRequirement().addList("api_key")))
.info(new Info()
.title("Your API")
.description("Your API")
.version(this.buildProperties.getVersion())
.contact(new Contact()
.name("Example Inc")
.url("https://www.example.com/")
.email("developer@example.com")));
}
@Bean
public OpenApiCustomiser openApiCustomiser() {
return openApi -> openApi.getPaths().values().stream()
.flatMap(pathItem -> pathItem.readOperations().stream())
.forEach(operation -> operation.addParametersItem(new HeaderParameter()
.$ref("#/components/parameters/Version")));
}
}
This will get you set up will all three of the requirements, including the Version:
header: