Spring Boot 3 OpenAPI Documentation with Springdoc

Spring Boot is the most used Java framework for creating REST APIs. A good REST API must always provide equally good documentation. In this tutorial, we will learn to generate REST API documentation using Springdoc-OpenAPI 3.0 for Spring Boot 2 and Spring Boot 3 applications.

1. Introduction to OpenAPI 3.0 and SpringDoc

The OpenAPI Specification (OAS) defines a standard, programming language-agnostic interface description for HTTP APIs, which allows both humans and computers to discover and understand. When properly defined via OpenAPI, a consumer can understand and interact with the remote service with a minimal amount of implementation logic.

The springdoc-openapi library helps to automate the generation of Spring-based REST APIs in OpenAPI 3.0 format. It examines the application at runtime to infer API semantics based on class annotations and configuration beans.

By default, SpringDoc automatically generates documentation in JSON/YAML formats. When Swagger UI is enabled, it uses Swagger API to generate the documentation in HTML format, too.

SpringDoc supports most of the Spring modules out of the box. It is able to examine the code in runtime for all these modules and generate appropriate documentation for them.

2. Maven

The recommended way to include the springdoc-openapi-ui dependency is including via its starter dependency springdoc-openapi-starter-webmvc-ui.

   <dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
      <version>2.1.0</version>
   </dependency>

In non-Spring Boot projects, we can include the springdoc-openapi-ui dependency manually.

<dependency>
	<groupId>org.springdoc</groupId>
	<artifactId>springdoc-openapi-ui</artifactId>
	<version>1.6.11</version>
</dependency>

The springdoc-openapi v1.7.0 is the last release supporting Spring Boot 2.x and 1.x.

To exclude Swagger UI support, we can include the specific dependencies for Spring modules. Such as for generating the API information in the JSON and YAML formats only, for Spring WebMVC APIs, include the following dependency. Notice that it has “API” at the end instead of “ui“.

   <dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
      <version>2.1.0</version>
   </dependency>

Similarly, for Spring WebFlux reactive APIs, we can include springdoc-openapi-starter-webflux-api.

3. URLs to Access the API Docs

After adding the dependencies, we can access the OpenAPI description in JSON format at the ‘/v3/api-docs’ URL:

https://server:port/application-context-path/v3/api-docs

To access the OpenAPI information in YAML format, use the .yaml extension.

https://server:port/application-context-path/v3/api-docs.yaml

For the custom path of the OpenAPI documentation in JSON/YAML format, add the following custom property, in Spring Boot properties file:

springdoc.api-docs.path=/api-docs

3. Support for Swagger UI

As discussed in the previous section, Swagger UI is default supported when adding the springdoc-openapi-ui artifact. Lets understand it in more detail.

3.1. Default Generated Documentation

We can access the HTML documentation in the path: /swagger-ui.html

https://server:port/context-path/swagger-ui.html

3.2. Customize the Defaults

We can use the properties name-spaced with springdoc.swagger-ui.* to customize the swagger UI. We can define these properties in application.properties file, similar to other Spring boot properties.

...
springdoc.swagger-ui.enabled = true
springdoc.swagger-ui.path = /swagger-ui.html
springdoc.swagger-ui.tryItOutEnabled = false
springdoc.swagger-ui.filter = false
springdoc.swagger-ui.syntaxHighlight.activated = true
...

3.3. Disable Swagger-UI

To disable the swagger UI, simply set the springdoc.swagger-ui.enabled property to false.

springdoc.swagger-ui.enabled = false

4. Customizing Generated Docs using Annotations

The default-generated documentation is good enough to get started with. Over time, we will need to configure it to meet various requirements. Let us learn a few of these configurations.

4.1. Only Selected REST Controllers and API Methods

There are two ways to restrict SpringDoc from including specific REST controllers and API methods.

The first method is using the @io.swagger.v3.oas.annotations.Hidden annotation. We can apply this annotation on any API controller, API method or @ControllerAdvice exception handlers, and the SpringDoc will not generate the information for it.

@Hidden @RestController
public class EmployeeController {

}

//or skip the API methods

@Hidden @PostMapping("/employees")
Employee create(@RequestBody Employee employee)  {
  return employeeService.save(employee);
}

The second solution is using the springdoc.packagesToScan and springdoc.pathsToMatch properties. We can configure the package names or API URLs to skip from the API documentation.

# Packages to include
springdoc.packagesToScan = com.company.app.web.employee, com.company.app.web.account

# Paths to include
springdoc.pathsToMatch = /api/employee-management/**, /api/account-management/**

4.2. Custom HTTP Statuses using @ControllerAdvice and @ResponseStatus

An important part of API specification is the HTTP statuses returned from the API in different cases. A client must handle all the scenarios to make a robust application.

Generally, such exceptions are handled at the global level using the @RestControllerAdvice and @ExceptionHandler annotations. SpringDoc automatically detects these annotations and includes these statuses to the API information.

@RestControllerAdvice
class GlobalExceptionHandler {

  @ResponseStatus(HttpStatus.BAD_REQUEST)
  @ExceptionHandler(ValidationException.class)
  public ResponseEntity<String> invalidInputBodyHandler(ValidationException e) {
    return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
  }
}

The above handler will include the HTTP status 400 to all API responses.

Error responses in API Information

To disable this behavior of adding responses to all APIs, set the property springdoc.override-with-generic-response to false.

springdoc.override-with-generic-response = false

4.4. JSR-303 Bean Validation Annotations Support

SpringDoc, by default, supports the validations added to domain objects using the JSR-303 annotations. Suppose, we have the @NotNull annotation on two fields firstName and lastName.

@Entity
public class Employee {
	...

	@NotNull
	private String firstName;

	@NotNull
	private String lastName;
}

We can verify this restriction in the generated schema in API information.

JSR-303 annotations

4.3. Adding Pagination Information

Another important part of an API is providing the pagination formation if the number of records is large enough for a single request. Since springdoc-openapi v1.6.0, we need to combine @ParameterObject annotation with the Pageable type to generate the paging information automatically.

@GetMapping("/employees")
Page<Employee> getAllEmployees(@ParameterObject Pageable pageable) {
  return null;
}
API Pagination

If we want to disable the support of spring Pageable types, we can use:

springdoc.model-converters.pageable-converter.enabled=false

5. Support for Swagger Annotations

If we further customize the API documentation using the Swagger 3 annotations at each API level. These annotations are already present in springdoc-openapi-ui dependency.

We can use the annotations such as @Operation, @ApiResponse, @Parameter and @Tag to provide the API description manually.

@Operation(summary = "Get All Employees")
@ApiResponses(value = {
    @ApiResponse(responseCode = "200", 
    		description = "Employee List",
        content = { @Content(mediaType = "application/json",
        schema = @Schema(implementation = Page.class)) }),
    @ApiResponse(responseCode = "204", 
    		description = "No employee found",
        content = @Content) })

@GetMapping("/employees")
Page<Employee> read(@ParameterObject Pageable pageable) {
  return null;
}

6. Documentation of API Security

We need to add springdoc-openapi-security in combination with the springdoc-openapi-ui dependency. This dependency helps ignore @AuthenticationPrincipal in case it is used on REST Controllers.

<dependency>
   <groupId>org.springdoc</groupId>
   <artifactId>springdoc-openapi-security</artifactId>
   <version>1.6.11</version>
</dependency>

To define the API security scheme, we can use @SecurityScheme annotation:

@io.swagger.v3.oas.annotations.security.SecurityScheme(
    type = SecuritySchemeType.OAUTH2
)
@RestController
public class EmployeeController { ... }

Or we can define it programmatically, by overriding OpenAPI bean:

@Bean
public OpenAPI employeeManagementOpenAPI(@Value("${springdoc.version}") String appVersion) {
  return new OpenAPI()
      .components(new Components().addSecuritySchemes("basicScheme",
          new SecurityScheme().type(SecurityScheme.Type.OAUTH2).scheme("OAUTH2")))
      .info(new Info().title("Employee Management API").version(appVersion)
          .license(new License().name("Apache 2.0").url("http://howtodoinjava.com")));
}

7. Conclusion

SpringDoc-OpenAPI is really easy to use and can get you pretty fast to a well-documented REST API. Though, we must keep in mind that the generated documentation is based on used annotations and defined properties. These can be added or removed accidentally, anytime and thus making the API documentation outdated.

A good solution is Spring REST docs that create documentation based on the unit tests. If a test fails then the documentation won’t be created for it. This is also a good approach to keep the source code, unit tests and documentation in sync, all the time.

Happy Learning !!

Source Code on Github

Comments

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial

Dark Mode

Dark Mode