This library automagically generates a OpenApi v3 specification at runtime for Spring Boot applications.
It aims at fully analyzing Spring request mappings augmented by Swagger annotations to provide a self-descriptive API specification of your application.
- Spring WebMVC support including content negotiation support
- Spring WebFlux support including Router Functions
- Integrated Swagger UI
- Swagger Annotations v3 support
- No dependency on swagger-core module or swagger-models module
- Extended support for
Schema
building, including self-referencing types and Jackson polymorphism
Note that some features are not fully implemented yet, see issues.
Inside your Spring Boot application, add the following (maven) dependency:
<dependency>
<groupId>de.qaware.tools.openapi-generator-for-spring</groupId>
<artifactId>openapi-generator-for-spring-starter</artifactId>
<version>6.0.0</version>
</dependency>
After starting your application, the OpenApi v3 specification of your application is provided at /v3/api-docs
as JSON.
This specification can be viewed by visiting /swagger-ui
inside your browser (relative to context path).
Have a look at the Demo for WebMVC and Demo for WebFlux for a first impression.
The following configuration properties are available with the prefix openapi-generator-for-spring.
:
The following extension properties are currently part of this library:
The library supports filtering at the following stages during OpenApi specification building, in this order:
- HandlerMethodFilter filters before passing on the found handler methods to the path building.
- OperationPreFilter
filters before the
Operation
model object is built. - OperationParameterPreFilter
filters before a
Parameter
model object of an operation is built. - OperationParameterPostFilter
filters after a
Parameter
has been built. - OperationPostFilter
filters after a
Operation
has been built. All information has been set except referenced components. - PathItemFilter
filters after a
PathItem
is fully constructed. All information has been set except referenced components.
Insert a bean extending one or more of the above interfaces, which will be picked up by the library.
The later the filter is called the more work has been done, but also more information is supplied to make the filtering decision. Possibly referenced components must be manually cleared later on in an extra customization step if filtering happened too late. It is thus recommended applying filtering as early as possible.
Grouping is realized by applying filters, preferably a OperationPreFilter
, while building the OpenAPI specification.
Query and header parameters of the HTTP request to /v3/api-docs
can be obtained within the filter by auto-wiring the
bean of type OpenApiRequestParameterProvider
.
This way, you can control which operations are considered for the specification when /v3/api-docs?group=MyGroup
. The
Swagger UI can also be customized to display more than one specification by providing a bean of type
OpenApiSwaggerUiApiDocsUrisSupplier
.
See the *Configuration
class of this
integration test
or this
integration test
for a fully working WebMVC or WebFlux example, respectively. Note that the test cases invoke the endpoint with different
header or query parameters.
The library offers various customizers, which allow the library user to (hopefully) adapt to any use case which comes to mind.
The following shows some examples for customizers:
- SchemaCustomizer customizes a constructed Schema . An example is the SchemaCustomizerForNullable .
- OperationCustomizer customizes a constructed Operation . An example is the DefaultOperationIdCustomizer which sets the Operation ID from an OperationIdProvider bean.
- This integration test shows an example how to override the default identifier when referencing request bodies.
Feel free to investigate the
api module
for more details. The relevant interfaces all have the suffix Customizer
and extend the Ordered
interface.
OperationCustomizer
bean that uses the class name of the RestController to set it as OpenAPI tag
/**
* Provide an OperationCustomizer to use the class name of the REST controller as Tag. This way the API endpoints are grouped per REST controller.
*
* @return OperationCustomizer
*/
@Bean
public OperationCustomizer operationTagCustomizer() {
return (operation, operationBuilderContext) -> {
if (CollectionUtils.isEmpty(operation.getTags())) {
operationBuilderContext.getHandlerMethod(SpringWebHandlerMethod.class).ifPresent(handlerMethod -> {
String declaringClassName = handlerMethod.getMethod().getMethod().getDeclaringClass().getSimpleName();
operation.setTags(singletonList(declaringClassName));
operationBuilderContext.getReferencedItemConsumer(ReferencedTagsConsumer.class)
.accept(singletonList(Tag.builder().name(declaringClassName).build()));
});
}
};
}
OperationIdProvider
to generate deep-links to specific endpoints that are compatible to the SpringFox style
/**
* Provide an OperationIdProvider to generate deep-links that are compatible to the SpringFox style.
*
* @return OperationIdProvider
*/
@Bean
public OperationIdProvider operationIdProvider() {
return operationInfo -> operationInfo.getHandlerMethod().getIdentifier() + "Using" + operationInfo.getRequestMethod().name();
}
The Swagger UI index.html
is generated from a
Mustache template
and uses the
Swagger UI Webjar
distribution.
The default implementation of
OpenApiSwaggerUiApiDocsUrisSupplier
uses the given URI to the API Docs endpoint and names the entry Default
. This name is ignored as there is only one
entry in the Swagger UI.
See this integration test for an example how to customize the offered API Docs within the Swagger UI.
Define the following bean of type InitialTypeBuilder
if you want to resolve the type YourType
always as if it was of
type String
:
@Bean
public InitialTypeBuilder openApiSchemaTypeSubstitutionForYourType(){
return(caller,javaType,annotationsSupplier,recursiveBuilder)->{
if(javaType.getRawClass().equals(YourType.class)){
return recursiveBuilder.build(String.class, annotationsSupplier);
}
return null;
};
}
Spring (Boot) offers to handle exceptions from handler methods via
@ExceptionHandler
annotated methods. This mechanism can be plugged into the specification by using
an OperationCustomizer
, which scans a SpringWebHandlerMethod
for its exception signature and adds
additional ApiResponse
s to the Operation
for each exception.
One can even figure out the @ExceptionHandler
method, as Spring would do, to automatically determine the Schema
of
the error response and also scan for @ReponseStatus
to determine the error code.
It is also possible to throw an error when there is an exception declared but no appropriate @ExceptionHandler
method
is found.
See this configuration of the integration test for a fully worked out example.
This library is based on experience while using Spring Fox and SpringDoc OpenApi. As those libraries have turned out to be not flexible enough for our internal projects, this library aims at being fully customizable.
Composing Spring beans in combination with Spring Boot autoconfiguration enable this flexibility. The library offers
opinionated (and hopefully sane) default implementations but marks all of them with @ConditionalOnMissingBean
. It is
encouraged to override those defaults by providing own bean implementations.
Default implementations in common
module will use the api
module interfaces as much as possible. This way it is ensured that the provided api module actually offers useful
interfaces.
All the following module names are prefixed with openapi-generator-for-spring-
.
model contains Jackson-serializable POJOs to represent the OpenApi v3 model.
api contains the public API to extend and adapt the functionality of this library.
common contains the main algorithm parsing the swagger-annotated handler
methods. It provides default implementations for most of the interfaces in openapi-generator-for-spring-api
module.
autoconfigure contains the Spring Boot auto-configuration of common beans.
web shared support code for Spring WebMVC and WebFlux including shared auto-configuration.
webmvc supports Spring WebMVC via Spring Boot auto-configuration.
webflux supports Spring WebFlux via Spring Boot auto-configuration.
ui Provides Swagger UI below /swagger-ui
. Offers UI Resource transformation for
WebMVC and WebFlux and sets up correct redirect routes.
starter Opinionated choice of dependencies. Enables Swagger UI and support for WebMVC and WebFlux if present.
test contains all integration tests for WebMVC and WebFlux.
shaded contains shaded dependencies to avoid interference with Spring Boot autoconfiguration. This library does not want to trigger Mustache or WebJar exposure for users of this library. Shading is the only mechanism which still allows to use such code but hide it from Spring Boot.
Each module aims to have minimal dependencies. General library dependencies are:
- Spring Core (Web/WebMVC/WebFlux are optional)
- Jackson
- Swagger Annotations
- WebJar for Swagger UI (shaded)
- Mustache (shaded)
- Apache Commons
Please open an issue before posting a pull request unless you have a very obvious fix or improvement to contribute.
When developing with IntelliJ, run mvn clean package -DskipTests
first in order to get the integration tests also
running from within the IDE.