F.A.Q
How can I define multiple OpenAPI definitions in one Spring Boot project?
You can define your own groups of API based on the combination of: API paths and packages to scan. Each group should have a unique groupName
.
The OpenAPI description of this group, will be available by default on:
-
http://server:port/context-path/v3/api-docs/groupName
To enable the support of multiple OpenAPI definitions, a bean of type GroupedOpenApi
needs to be defined.
For the following Group definition(based on package path), the OpenAPI description URL will be : /v3/api-docs/stores
@Bean
public GroupedOpenApi storeOpenApi() {
String paths[] = {"/store/**"};
return GroupedOpenApi.builder().group("stores").pathsToMatch(paths)
.build();
}
For the following Group definition (based on package name), the OpenAPI description URL will be: /v3/api-docs/users
@Bean
public GroupedOpenApi userOpenApi() {
String packagesToscan[] = {"test.org.springdoc.api.app68.api.user"};
return GroupedOpenApi.builder().group("users").packagesToScan(packagesToscan)
.build();
}
For the following Group definition(based on path), the OpenAPI description URL will be: /v3/api-docs/pets
@Bean
public GroupedOpenApi petOpenApi() {
String paths[] = {"/pet/**"};
return GroupedOpenApi.builder().group("pets").pathsToMatch(paths)
.build();
}
For the following Group definition (based on package name and path), the OpenAPI description URL will be: /v3/api-docs/groups
@Bean
public GroupedOpenApi groupOpenApi() {
String paths[] = {"/v1/**"};
String packagesToscan[] = {"test.org.springdoc.api.app68.api.user", "test.org.springdoc.api.app68.api.store"};
return GroupedOpenApi.builder().group("groups").pathsToMatch(paths).packagesToScan(packagesToscan)
.build();
}
For more details about the usage, you can have a look at the following sample Test:
How can I configure Swagger UI?
-
The support of the swagger official properties is available on
springdoc-openapi
. See Official documentation. -
You can use the same swagger properties in the documentation as Spring Boot properties.
All these properties should be declared with the following prefix: springdoc.swagger-ui
|
How can I filter the resources documented in the output specification by the provided group?
-
You can use the standard
swagger-ui
property filter.
springdoc.swagger-ui.filter=group-a
How can I disable/enable Swagger UI generation based on env variable?
-
This property helps you disable only the UI.
springdoc.swagger-ui.enabled=false
How can I control the default expansion setting for the operations and tags, in the Swagger UI ,
-
You can set this property in your application.yml like so for example:
springdoc.swagger-ui.doc-expansion= none
How can I change the layout of the swagger-ui
?
-
For layout options, you can use swagger-ui configuration options. For example:
springdoc.swagger-ui.layout=BaseLayout
How can I sort endpoints alphabetically?
-
You can use the following
springdoc-openapi
properties:
#For sorting endpoints alphabetically springdoc.swagger-ui.operationsSorter=alpha #For sorting tags alphabetically springdoc.swagger-ui.tagsSorter=alpha
How can I disable the try it out button?
-
You have to set the following property:
springdoc.swagger-ui.supportedSubmitMethods="get", "put", "post", "delete", "options", "head", "patch", "trace"
How can i apply enumAsRef = true
to all enums ?
-
Declare the following property:
static { io.swagger.v3.core.jackson.ModelResolver.enumsAsRef = true; }
How can I explicitly set which paths to filter?
-
You can set list of paths to include using the following property:
springdoc.pathsToMatch=/v1, /api/balance/**
How can I explicitly set which packages to scan?
-
You can set list of packages to include using the following property:
springdoc.packagesToScan=package1, package2
How can I set Swagger properties programmatically?
These can be set by creating a swaggerUiConfig
bean as follows:
@Bean
@Primary
fun swaggerUiConfig(config: SwaggerUiConfigProperties): SwaggerUiConfigProperties {
config.showCommonExtensions = true
config.queryConfigEnabled = true
return config
}
How can I ignore some field of model ?
-
You can use the following annotation on the top of the field that you want to hide:
-
@Schema(hidden = true)
How can I ignore @AuthenticationPrincipal
parameter from spring-security ?
-
A solution workaround would be to use:
@Parameter(hidden = true)
-
The projects that use
spring-boot-starter-security
orspring-security-oauth2-authorization-server
should use:-
springdoc-openapi-starter-webmvc-api
if they depend onspring-boot-starter-web
and they only need the access to the OpenAPI endpoints. -
OR
springdoc-openapi-starter-webmvc-ui
, if they depend onspring-boot-starter-web
and they also need the access to the swagger-ui. -
OR
springdoc-openapi-starter-webflux-api
if they depend onspring-boot-starter-webflux
and they only the access to the OpenAPI endpoints. -
OR
springdoc-openapi-starter-webflux-ui
, if they depend onspring-boot-starter-webflux
and they also need the access to the swagger-ui.
-
Is there a Gradle plugin available?
-
Yes. More details are available, in the gradle plugin section.
Does springdoc-openapi
support Jersey?
-
If you are using JAX-RS and as implementation Jersey (
@Path
for example), we do not support it. -
We only support exposing Rest Endpoints using Spring managed beans (
@RestController
for example). -
You can have a look at swagger-jaxrs2 project:
Can springdoc-openapi
generate API only for @RestController
?
-
@RestController
is equivalent to@Controller
+@RequestMapping
on the type level. -
For some legacy apps, we are constrained to still support both.
-
If you need to hide the
@Controller
on the type level, in this case, you can use:@Hidden
on controller level. -
Please note this annotation can be also used to hide some methods from the generated documentation.
Are the following validation annotations supported : @NotEmpty
@NotBlank
@PositiveOrZero
@NegativeOrZero
?
-
Yes
How can I map Pageable
(spring-data-commons) object to correct URL-Parameter in Swagger UI?
The support for Pageable of spring-data-commons is available out-of-the box since springdoc-openapi v1.6.0
.
For this, you have to combine @ParameterObject
annotation with the Pageable
type.
Before springdoc-openapi v1.6.0
:
-
You can use as well
@ParameterObject
instead of@PageableAsQueryParam
for HTTPGET
methods.
static {
getConfig().replaceParameterObjectWithClass(org.springframework.data.domain.Pageable.class, Pageable.class)
.replaceParameterObjectWithClass(org.springframework.data.domain.PageRequest.class, Pageable.class);
}
-
Another solution, is to configure Pageable manually:
-
you will have to declare the explicit mapping of Pageable fields as Query Params and add the
@Parameter(hidden = true) Pageable pageable
on your pageable parameter. -
You should also, declare the annotation
@PageableAsQueryParam
provided byspringdoc-openapi
on the method level, or declare your own if need to define your custom description, defaultValue, …
-
If you want to disable the support of spring Pageable Type, you can use:
springdoc.model-converters.pageable-converter.enabled=false
The property springdoc.model-converters.pageable-converter.enabled is only available since v1.5.11+
|
How can I generate enums in the generated description?
-
You could add a property
allowableValues
, to@Parameter
. For example:
@GetMapping("/example")
public Object example(@Parameter(name ="json", schema = @Schema(description = "var 1",type = "string", allowableValues = {"1", "2"}))
String json) {
return null;
}
-
or you could override
toString
on your enum:
@Override
@JsonValue
public String toString() {
return String.valueOf(action);
}
How can I deploy springdoc-openapi-starter-webmvc-ui
behind a reverse proxy?
-
If your application is running behind a proxy, a load-balancer or in the cloud, the request information (like the host, port, scheme…) might change along the way. Your application may be running on
10.10.10.10:8080
, but HTTP clients should only seeexample.org
. -
RFC7239 "Forwarded Headers" defines the Forwarded HTTP header; proxies can use this header to provide information about the original request. You can configure your application to read those headers and automatically use that information when creating links and sending them to clients in HTTP 302 responses, JSON documents or HTML pages. There are also non-standard headers, like
X-Forwarded-Host
,X-Forwarded-Port
,X-Forwarded-Proto
,X-Forwarded-Ssl
, andX-Forwarded-Prefix
. -
If the proxy adds the commonly used
X-Forwarded-For
andX-Forwarded-Proto headers
, setting server.forward-headers-strategy to NATIVE is enough to support those. With this option, the Web servers themselves natively support this feature; you can check their specific documentation to learn about specific behavior. -
You need to make sure the following header is set in your reverse proxy configuration:
X-Forwarded-Prefix
-
For example, using Apache 2, configuration:
RequestHeader set X-Forwarded-Prefix "/custom-path"
-
Then, in your Spring Boot application make sure your application handles this header:
X-Forwarded-For
. There are two ways to achieve this:
server.use-forward-headers=true
-
If this is not enough, Spring Framework provides a
ForwardedHeaderFilter
. You can register it as a Servlet Filter in your application by setting server.forward-headers-strategy is set to FRAMEWORK. -
Since Spring Boot 2.2, this is the new property to handle reverse proxy headers:
server.forward-headers-strategy=framework
-
And you can add the following bean to your application:
@Bean
ForwardedHeaderFilter forwardedHeaderFilter() {
return new ForwardedHeaderFilter();
}
-
If you need to manually adjust the URL displayed in the Swagger UI, implement the
ServerBaseUrlCustomizer
interface. This might be necessary to remove the port number, for example.
@Bean
public class CustomServerBaseUrlCustomizer implements ServerBaseUrlCustomizer {
@Override
public String customize(String serverBaseUrl) {
try {
URL url = new URL(serverBaseUrl);
if (url.getHost().contains(".com")) {
serverBaseUrl = new URL(url.getProtocol(),url.getHost(),url.getFile()).toString();
}
} catch (MalformedURLException ex) {
// nothing we can do
}
return serverBaseUrl;
}
}
Adding springdoc-openapi-starter-webmvc-ui
dependency breaks my public/index.html
welcome page
-
If you already have static content on your root, and you don’t want it to be overridden by
springdoc-openapi-starter-webmvc-ui
configuration, you can just define a custom configuration of theswagger-ui
, in order not to override the configuration of your files from in your context-root: -
For example use:
springdoc.swagger-ui.path= /swagger-ui/api-docs.html
How can I customise the OpenAPI object ?
-
You can write your own implementation of
OpenApiCustomizer
. -
An example is available on:
@Bean
public OpenApiCustomizer consumerTypeHeaderOpenAPICustomizer() {
return openApi -> openApi.getPaths().values().stream().flatMap(pathItem -> pathItem.readOperations().stream())
.forEach(operation -> operation.addParametersItem(new HeaderParameter().$ref("#/components/parameters/myConsumerTypeHeader")));
}
This bean OpenApiCustomizer will be applied to the Default OpenAPI only.
|
If you need the OpenApiCustomizer
to applied to GroupedOpenApi
as well, then use GlobalOpenApiCustomizer
instead.
How can I return an empty content as response?
-
It is be possible to handle as return an empty content as response using, one of the following syntaxes:
-
content = @Content
-
content = @Content(schema = @Schema(hidden = true))
-
For example:
@Operation(summary = "Get thing", responses = {
@ApiResponse(description = "Successful Operation", responseCode = "200", content = @Content(mediaType = "application/json", schema = @Schema(implementation = String.class))),
@ApiResponse(responseCode = "404", description = "Not found", content = @Content),
@ApiResponse(responseCode = "401", description = "Authentication Failure", content = @Content(schema = @Schema(hidden = true))) })
@RequestMapping(path = "/testme", method = RequestMethod.GET)
ResponseEntity<String> testme() {
return ResponseEntity.ok("Hello");
}
How are endpoints with multiple consuming media types supported?
-
An overloaded method on the same class, with the same HTTP Method and path, will have as a result, only one OpenAPI Operation generated.
-
In addition, it’s recommended to have the
@Operation
in the level of one of the overloaded methods. Otherwise it might be overridden if it’s declared many times within the same overloaded method.
How can I get yaml and json (OpenAPI) in compile time?
-
You can use
springdoc-openapi-maven-plugin
for this functionality: -
You can customise the output directory (property outputDir): The default value is: ${project.build.directory}
What are the ignored types in the documentation?
-
Principal
,Locale
,HttpServletRequest
andHttpServletResponse
and other injectable parameters supported by Spring MVC are excluded. -
Full documentation here:
How can i disable ignored types:
If you don’t want to ignore the types Principal
, Locale
, HttpServletRequest
, and others,:
SpringDocUtils.getConfig().removeRequestWrapperToIgnore(HttpServletRequest.class)
How do I add authorization header in requests?
-
You should add the
@SecurityRequirement
tags to your protected APIs. -
For example:
@Operation(security = { @SecurityRequirement(name = "bearer-key") })
-
And the security definition sample:
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.components(new Components()
.addSecuritySchemes("bearer-key",
new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT")));
}
Differentiation to Springfox project
-
OAS 3 was released in July 2017, and there was no release of
springfox
to support OAS 3.springfox
covers for the moment only swagger 2 integration with Spring Boot. The latest release date is June 2018. So, in terms of maintenance there is a big lack of support lately. -
We decided to move forward and share the library that we already used on our internal projects, with the community.
-
The biggest difference with
springfox
, is that we integrate new features not covered byspringfox
: -
The integration between Spring Boot and OpenAPI 3 standard.
-
We rely on on
swagger-annotations
andswagger-ui
only official libraries. -
We support new features on Spring 5, like
spring-webflux
with annotated and functional style. -
We do our best to answer all the questions and address all issues or enhancement requests
How do I migrate to OpenAPI 3 with springdoc-openapi
-
There is no relation between
springdoc-openapi
andspringfox
.If you want to migrate to OpenAPI 3: -
Remove all the dependencies and the related code to springfox
-
Add
springdoc-openapi-starter-webmvc-ui
dependency -
If you don’t want to serve the UI from your root path or there is a conflict with an existing configuration, you can just change the following property:
springdoc.swagger-ui.path=/you-path/swagger-ui.html
How can I set a global header?
-
You may have global parameters with Standard OpenAPI description.
-
If you need the definitions to appear globally (within every group), no matter if the group fulfills the conditions specified on the GroupedOpenApi , you can use OpenAPI Bean.
-
You can define common parameters under parameters in the global components section and reference them elsewhere via
$ref
. You can also define global header parameters. -
For this, you can override to OpenAPI Bean, and set the global headers or parameters definition on the components level.
@Bean
public OpenAPI customOpenAPI(@Value("${springdoc.version}") String appVersion) {
return new OpenAPI()
.components(new Components().addSecuritySchemes("basicScheme", new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic"))
.addParameters("myHeader1", new Parameter().in("header").schema(new StringSchema()).name("myHeader1")).addHeaders("myHeader2", new Header().description("myHeader2 header").schema(new StringSchema())))
.info(new Info()
.title("Petstore API")
.version(appVersion)
.description("This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.")
.termsOfService("http://swagger.io/terms/")
.license(new License().name("Apache 2.0").url("http://springdoc.org")));
}
How can I define SecurityScheme ?
-
You can use:
@SecurityScheme
annotation. -
Or you can define it programmatically, by overriding OpenAPI Bean:
@Bean
public OpenAPI customOpenAPI(@Value("${springdoc.version}") String appVersion) {
return new OpenAPI()
.components(new Components().addSecuritySchemes("basicScheme",
new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic")))
info(new Info().title("SpringShop API").version(appVersion)
.license(new License().name("Apache 2.0").url("http://springdoc.org")));
}
How can I hide an operation or a controller from documentation ?
-
You can use
@io.swagger.v3.oas.annotations.Hidden
annotation at@RestController
,@RestControllerAdvice
and method level -
The
@Hidden
annotation on exception handler methods, is considered when building generic (error) responses from@ControllerAdvice
exception handlers. -
Or use:
@Operation(hidden = true)
How to configure global security schemes?
-
For global SecurityScheme, you can add it inside your own OpenAPI definition:
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI().components(new Components()
.addSecuritySchemes("basicScheme", new SecurityScheme()
.type(SecurityScheme.Type.HTTP).scheme("basic"))).info(new Info().title("Custom API")
.version("100")).addTagsItem(new Tag().name("mytag"));
}
Can I use spring property with swagger annotations?
-
The support of spring property resolver for
@Info
:title
*description
*version
*termsOfService
-
The support of spring property resolver for
@Info.license
:name
*url
-
The support of spring property resolver for
@Info.contact
:name
*email
*url
-
The support of spring property resolver for
@Operation
:description
*summary
-
The support of spring property resolver for
@Parameter
:description
*name
-
The support of spring property resolver for
@ApiResponse
:description
-
Its also possible to declare security URLs for
@OAuthFlow
:openIdConnectUrl
*authorizationUrl
*refreshUrl
*tokenUrl
-
The support of spring property resolver for
@Schema
:name
*title
*description
, by settingspringdoc.api-docs.resolve-schema-properties
totrue
-
The support of spring property resolver for
@ExtensionProperty
by settingspringdoc.api-docs.resolve-extensions-properties
totrue
How is server URL generated ?
-
Generating automatically server URL may be useful, if the documentation is not present.
-
If the server annotations are present, they will be used instead.
How can I disable springdoc-openapi cache?
-
By default, the OpenAPI description is calculated once, and then cached.
-
Sometimes the same swagger-ui is served behind internal and external proxies. some users want the server URL, to be computed on each http request.
-
In order to disable springdoc cache, you will have to set the following property:
springdoc.cache.disabled= true
How can I expose the mvc api-docs endpoints without using the swagger-ui
?
-
You should use the
springdoc-openapi-core
dependency only:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
<version>latest.version</version>
</dependency>
How can I disable springdoc-openapi
endpoints ?
-
Use the following property:
springdoc.api-docs.enabled=false
How can I hide Schema of the the response ?
-
To hide the response element, using
@Schema
annotation, as follows, at operation level:
@Operation(responses = @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(hidden = true))))
-
Or directly at
@ApiResponses
level:
@ApiResponses(value = {@ApiResponse(responseCode = "200", content = @Content(schema = @Schema(hidden = true))) }) OR @ApiResponse(responseCode = "404", description = "Not found", content = @Content)
What is the URL of the swagger-ui
, when I set a different context-path?
-
If you use different context-path:
server.servlet.context-path= /foo
-
The
swagger-ui
will be available on the following URL:-
http://server:port/foo/swagger-ui.html
-
Can I customize OpenAPI object programmatically?
-
You can Define your own OpenAPI Bean: If you need the definitions to appear globally (within every group), no matter if the group fulfills the conditions specified on the GroupedOpenApi , you can use OpenAPI Bean.
@Bean
public OpenAPI customOpenAPI(@Value("${springdoc.version}") String appVersion) {
return new OpenAPI()
.components(new Components().addSecuritySchemes("basicScheme",
new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic")))
.info(new Info().title("SpringShop API").version(appVersion)
.license(new License().name("Apache 2.0").url("http://springdoc.org")));
}
-
If you need the definitions to appear within a specific group, and respect the conditions specified on the GroupedOpenApi, you can add OpenApiCustomizer to your GroupedOpenApi definition.
GroupedOpenApi.builder().group("users").pathsToMatch(paths).packagesToScan(packagedToMatch).addOpenApiCustomizer(customerGlobalHeaderOpenApiCustomizer())
.build()
@Bean
public OpenApiCustomizer customerGlobalHeaderOpenApiCustomizer() {
return openApi -> openApi.path("/foo",
new PathItem().get(new Operation().operationId("foo").responses(new ApiResponses()
.addApiResponse("default",new ApiResponse().description("")
.content(new Content().addMediaType("fatz", new MediaType()))))));
}
Where can I find the source code of the demo applications?
-
The source code of the application is available at the following GitHub repository:
Is file upload supported ?
-
The library supports the main file types:
MultipartFile
,@RequestPart
,FilePart
-
You can upload a file as follows:
@PostMapping(value = "/upload", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
public ResponseEntity<?> upload(@Parameter(description = "file") final MultipartFile file) {
return null;
}
@PostMapping(value = "/uploadFileWithQuery", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
public ResponseEntity<?> uploadFileWithQuery(@Parameter(description = "file") @RequestPart("file") final MultipartFile file,
@Parameter(description = "An extra query parameter") @RequestParam String name) {
return null;
}
@PostMapping(value = "/uploadFileWithJson", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}, produces = {
MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<?> uploadFileWithJson(
@RequestBody(content = @Content(encoding = @Encoding(name = "jsonRequest", contentType = MediaType.APPLICATION_JSON_VALUE)))
@Parameter(description = "An extra JSON payload sent with file") @RequestPart("jsonRequest") final JsonRequest jsonRequest,
@RequestPart("file") final MultipartFile file) {
return null;
}
Why my parameter is marked as required?
-
Any
@GetMapping
parameters is marked as required, even if@RequestParam
is missing. -
You can add
@Parameter(required=false)
annotation if you need different behaviour. -
Query parameters with
defaultValue
specified are marked as required.
How are overloaded methods with the same endpoints, but with different parameters
-
springdoc-openapi
renders these methods as a single endpoint. It detects the overloaded endpoints, and generates parameters.schema.oneOf.
What is a proper way to set up Swagger UI to use provided spec.yml?
-
With this property, all the
springdoc-openapi
auto-configuration beans are disabled:
springdoc.api-docs.enabled=false
-
Then enable the minimal Beans configuration, by adding this Bean:
@Bean
SpringDocConfiguration springDocConfiguration(){
return new SpringDocConfiguration();
}
@Bean
SpringDocConfigProperties springDocConfigProperties() {
return new SpringDocConfigProperties();
}
@Bean
ObjectMapperProvider objectMapperProvider(SpringDocConfigProperties springDocConfigProperties){
return new ObjectMapperProvider(springDocConfigProperties);
}
@Bean
SpringDocUIConfiguration SpringDocUIConfiguration(Optional<SwaggerUiConfigProperties> optionalSwaggerUiConfigProperties){
return new SpringDocUIConfiguration(optionalSwaggerUiConfigProperties);
}
-
Then configure, the path of your custom UI yaml file.
springdoc.swagger-ui.url=/api-docs.yaml
Is there a way to send authorization header through the @Parameter tag?
-
The OpenAPI 3 specification does not allow explicitly adding Authorization header.
Note: Header parameters named Accept, Content-Type and Authorization are not allowed. To describe these headers
-
For more information, you can read:
My Rest Controller using @Controller annotation is ignored?
-
This is the default behaviour if your
@Controller
doesn’t have annotation@ResponseBody
-
You can change your controllers to
@RestControllers
. Or add@ResponseBody
+@Controller
. -
If its not possible, you can configure springdoc to scan you additional controller using SpringDocUtils. For example:
static {
SpringDocUtils.getConfig().addRestControllers(HelloController.class);
}
How can I define groups using application.yml?
-
You can load groups dynamically using spring-boot configuration files.
-
Note that, for this usage, you don’t have to declare the GroupedOpenApi Bean.
-
You need to declare the following properties, under the prefix springdoc.group-configs.
-
For example:
springdoc.group-configs[0].group=users springdoc.group-configs[0].paths-to-match=/user/** springdoc.group-configs[0].packages-to-scan=test.org.springdoc.api
-
The list of properties under this prefix, are available here:
How can I extract fields from parameter object ?
-
You can use springdoc annotation @ParameterObject.
-
Request parameter annotated with @ParameterObject will help adding each field of the parameter as a separate request parameter.
-
This is compatible with Spring MVC request parameters mapping to POJO object.
-
This annotation does not support nested parameter objects.
-
POJO object must contain getters for fields with mandatory prefix
get
. Otherwise, the swagger documentation will not show the fields of the annotated entity.
How can I use the last springdoc-openapi
SNAPSHOT ?
-
For testing purposes only, you can test temporarily using the last
springdoc-openapi
SNAPSHOT -
To achieve that, you can on your pom.xml or your settings.xml the following section:
<repositories>
<repository>
<id>snapshots-repo</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
<releases><enabled>false</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
How can I use enable springdoc-openapi
MonetaryAmount support ?
-
If an application wants to enable the
springdoc-openapi
support, it declares:
SpringDocUtils.getConfig().replaceWithClass(MonetaryAmount.class, org.springdoc.core.converters.models.MonetaryAmount.class);
-
Another solution, without using springdoc-openapi MonetaryAmount, would be:
SpringDocUtils.getConfig().replaceWithSchema(MonetaryAmount.class, new ObjectSchema()
.addProperties("amount", new NumberSchema()).example(99.96)
.addProperties("currency", new StringSchema().example("USD")));
How can i aggregate external endpoints (exposing OPENAPI 3 spec) inside one single application?
The properties springdoc.swagger-ui.urls.*
, are suitable to configure external (/v3/api-docs url).
For example if you want to agreagte all the endpoints of other services, inside one single application.
IMPORTANT: Don’t forget that CORS needs to be enabled as well.
How can use custom json/yml file instead of generated one ?
If your file open-api.json, contains the OpenAPI documentation in OpenAPI 3 format. Then simply declare: The file name can be anything you want, from the moment your declaration is consistent yaml or json OpenAPI Spec.
springdoc.swagger-ui.url=/open-api.json
Then the file open-api.json, should be located in: src/main/resources/static No additional configuration is needed.
How can i enable CSRF support?
If you are using standard headers.( For example using spring-security headers) If the CSRF Token is required, swagger-ui automatically sends the new XSRF-TOKEN during each HTTP REQUEST.
If your XSRF-TOKEN isn’t standards-based, you can use a requestInterceptor to manually capture and attach the latest xsrf token to requests programmatically via spring resource transformer:
Starting from release v1.4.4 of springdoc-openapi, a new property is added to enable CSRF support, while using standard header names:
springdoc.swagger-ui.csrf.enabled=true
How can i disable the default swagger petstore URL?
You can use the following property:
springdoc.swagger-ui.disable-swagger-default-url=true
Is @PageableDefault supported, to enhance the OpenAPI 3 docuementation?
Yes, you can use it in conjunction with @ParameterObject
annotation.
Also, the spring-boot spring.data.web.
and spring.data.rest.default.
properties are supported since v1.4.5
How can i make spring security login-endpoint visible ?
You can use the following property:
springdoc.show-login-endpoint=true
How can i show schema definitions even the schema is not referenced?
You can use the following property:
springdoc.remove-broken-reference-definitions=false
How to override @Deprecated?
The whole idea of springdoc-openapi
is to get your documentation the closest to the code, with minimal code changes.
If the code contains @Deprecated
, sprindoc-openapi
will consider its schema as Deprecated as well.
If you want to declare a field on swagger as non deprecated, even with the java code, the field contains @Depreacted
,
You can use the following property that is available since release v1.4.3:
springdoc.model-converters.deprecating-converter.enabled=false
How can i display a method that returns ModelAndView?
You can use the following property:
springdoc.model-and-view-allowed=true
How can i have pretty-printed output of the OpenApi specification?
You can use the following property:
springdoc.writer-with-default-pretty-printer=true
How can i define different schemas for the same class?
Complex objects are always resolved as a reference to a schema defined in components.
For example let’s consider a Instance
class with an workAddress
and homeAddress
attribute of type Address
:
public class PersonDTO {
@JsonProperty
private String email;
@JsonProperty
private String firstName;
@JsonProperty
private String lastName;
@Schema(ref = "WorkAddressSchema")
@JsonProperty
private Address workAddress;
@Schema(ref = "HomeAddressSchema")
@JsonProperty
private Address homeAddress;
}
public class Address {
@JsonProperty
private String addressName;
}
If you want to define two different schemas for this class, you can set up 2 different schemas as follow:
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI().components(new Components()
.addSchemas("WorkAddressSchema", getSchemaWithDifferentDescription(Address.class, "work Address" ))
.addSchemas("HomeAddressSchema", getSchemaWithDifferentDescription(Address.class, "home Address" )));
}
private Schema getSchemaWithDifferentDescription(Class className, String description){
ResolvedSchema resolvedSchema = ModelConverters.getInstance()
.resolveAsResolvedSchema(
new AnnotatedType(className).resolveAsRef(false));
return resolvedSchema.schema.description(description);
}
How can i define different description for a class attribute depending on usage?
For example let’s consider a Instance
class with an email
attribute:
public class PersonDTO {
@JsonProperty
private String email;
@JsonProperty
private String firstName;
@JsonProperty
private String lastName;
}
If you want to define two different description for the email
, you can set up 2 different schemas as follow:
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI().components(new Components()
.addSchemas("PersonDTO1", getFieldSchemaWithDifferentDescription(PersonDTO.class, "work email" ))
.addSchemas("PersonDTO2", getFieldSchemaWithDifferentDescription(PersonDTO.class, "home email" )));
}
private Schema getFieldSchemaWithDifferentDescription(Class className, String description){
ResolvedSchema resolvedSchema = ModelConverters.getInstance()
.resolveAsResolvedSchema(
new AnnotatedType(className).resolveAsRef(false));
return resolvedSchema.schema.addProperties("email", new StringSchema().description(description));
}
Customizing swagger static resources
You can customize swagger documentation static resources located in META-INF/resources/webjars/swagger-ui/{swagger.version}/
. The list of resources includes:
-
index.html
-
swagger-ui-bundle.js
-
swagger-ui.css
-
swagger-ui-standalone-preset.js
-
swagger-ui.css.map
-
swagger-ui-bundle.js.map
-
swagger-ui-standalone-preset.js.map
-
favicon-32x32.png
To do this, you need to extend the implementation of SwaggerIndexPageTransformer
public class SwaggerCodeBlockTransformer
extends SwaggerIndexPageTransformer {
// < constructor >
@Override
public Resource transform(HttpServletRequest request,
Resource resource,
ResourceTransformerChain transformer)
throws IOException {
if (resource.toString().contains("swagger-ui.css")) {
final InputStream is = resource.getInputStream();
final InputStreamReader isr = new InputStreamReader(is);
try (BufferedReader br = new BufferedReader(isr)) {
final String css = br.lines().collect(Collectors.joining());
final byte[] transformedContent = css.replace("old", "new").getBytes();
return new TransformedResource(resource, transformedContent);
} // AutoCloseable br > isr > is
}
return super.transform(request, resource, transformer);
}
}
Next, add transformer @Bean
to your @Configuration
@Configuration
public class OpenApiConfig {
@Bean
public SwaggerIndexTransformer swaggerIndexTransformer(
SwaggerUiConfigProperties a,
SwaggerUiOAuthProperties b,
SwaggerUiConfigParameters c,
SwaggerWelcomeCommon d) {
return new SwaggerCodeBlockTransformer(a, b, c, d);
}
}
Illustrative example
Is GraalVM supported ?
The native support available added in spring-boot 3. If you have some time, do not hesitate to test it before the next release.
For the OpenAPI REST endpoints, you just need to build your application with the spring native
profile.
If you give @OpenAPIDefinition
or @SecurityScheme
to a class that has no implementation, that class will disappear when you natively compile.
To avoid this, give the class a @Configuration
.
@Configuration @OpenAPIDefinition(info = @Info(title = "My App", description = "description")) public class OpenAPIConfig { }
How to Integrate Open API 3 with Spring project (not Spring Boot)?
When your application is using spring without (spring-boot), you need to add beans and auto-configuration that are natively provided in spring-boot.
For example, lets assume you want load the swagger-ui in spring-mvc application:
-
You mainly, need to add the springdoc-openapi module
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>last.version</version>
</dependency>
-
If you don’t have the spring-boot and spring-boot-autoconfigure dependencies, you need to add them. And pay attention to the compatibility matrix, between you spring.version and spring-boot.version. For example, in this case (spring.version=5.1.12.RELEASE):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>3.3.3</version>
</dependency>
-
Scan for the
springdoc-openapi
'auto-configuration classes that spring-boot automatically loads for you. -
Depending on your module, you can find them on the file:
spring.factories
of eachspringdoc-openapi
module.
@Configuration
@EnableWebMvc
public class WebConfig implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) {
WebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("RestServlet",
new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/*");
}
private AnnotationConfigWebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(this.getClass(),
SpringDocConfiguration.class,
SpringDocConfigProperties.class,
SpringDocSpecPropertiesConfiguration.class,
SpringDocWebMvcConfiguration.class,
MultipleOpenApiSupportConfiguration.class,
SwaggerConfig.class,
SwaggerUiConfigProperties.class,
SwaggerUiOAuthProperties.class,
SpringDocUIConfiguration.class
);
return context;
}
}
-
Depending on your module, you can find them on the file:
org.springframework.boot.autoconfigure.AutoConfiguration.imports
of eachspringdoc-openapi
module. -
For groups usage make sure your
GroupedOpenApi
Beans are scanned. -
If additionally, you are using custom
context path
:/my-servlet-path
. Make sure you declare the following property:
spring.mvc.servlet.path=/my-servlet-path
What is the compatibility matrix of springdoc-openapi
with spring-boot
?
springdoc-openapi 2.x
is compatible with spring-boot 3
.
In general, you should only pick the last stable version as per today 2.6.0.
More precisely, this the exhaustive list of spring-boot versions against which springdoc-openapi
has been built:
spring-boot Versions |
Minimum springdoc-openapi Versions |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Why am i getting an error: Swagger UI unable to render definition
, when overriding the default spring registered HttpMessageConverter
?
When overriding the default spring-boot registered HttpMessageConverter
, you should have ByteArrayHttpMessageConverter
registered as well to have proper springdoc-openapi
support.
converters.add(new ByteArrayHttpMessageConverter());
converters.add(new MappingJackson2HttpMessageConverter(jacksonBuilder.build()));
Order is very important, when registering HttpMessageConverters .
|
Some parameters are not generated in the resulting OpenAPI spec.
The issue is caused by the changes introduced by Spring-Boot 3.2.0
in particular for the Parameter Name Discovery.
This can be fixed by adding the -parameters
arg to the Maven Compiler Plugin.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<parameters>true</parameters>
</configuration>
</plugin>