spring-rest-openapi-documentation
Documenting a Spring REST API Using OpenAPI 3.0
1. Overview
2. Setting up springdoc-openapi
To have springdoc-openapi automatically generate the OpenAPI 3 specification docs for our API, we simply add the springdoc-openapi-core dependency to our pom.xml:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-core</artifactId>
<version>1.1.44</version>
</dependency>
Then, when we run our application, the docs will be available at the path /v3/api-docs by default — for example:
http://localhost:8080/v3/api-docs/
To use a custom path, we can indicate in the application.properties file:
springdoc.api-docs.path=/api-docs
Now, we’ll be able to access the docs at:
http://localhost:8080/api-docs/
The OpenAPI definitions are in JSON _ format by default. For _yaml format, we can obtain the definitions at:
http://localhost:8080/api-docs.yaml
3. Setting up springdoc-openapi with Swagger UI
Besides generating the OpenAPI 3 specification itself, we can integrate springdoc-openapi with Swagger UI so that we can interact with our API specification and exercise the endpoints.
3.1. Maven Dependency
All we have to do to set up springdoc-openapi with Swagger UI is to add the dependency springdoc-openapi-ui to the project’s pom.xml:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.1.44</version>
</dependency>
We can now access the API documentation at:
http://localhost:8080/swagger-ui.html
We could customize the path by adding the property:
springdoc.swagger-ui.path=/swagger-ui-custom.html
3.2. Sample API
@RestController
@RequestMapping("/api/book")
public class BookController {
@Autowired
private BookRepository repository;
@GetMapping("/{id}")
public Book findById(@PathVariable long id) {
return repository.findById(id)
.orElseThrow(() -> new BookNotFoundException());
}
@GetMapping("/")
public Collection<Book> findBooks() {
return repository.getBooks();
}
@PutMapping("/{id}")
@ResponseStatus(HttpStatus.OK)
public Book updateBook(@PathVariable("id") final String id, @RequestBody final Book book) {
return book;
}
}
Then, when we run our application, we can view the documentation at:
http://localhost:8080/swagger-ui-custom.html
4. Integrating springdoc-openapi with Spring WebFlux
We can integrate springdoc-openapi and Swagger UI in a Spring WebFlux project by adding springdoc-openapi-webflux-ui:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-webflux-ui</artifactId>
<version>1.1.44</version>
</dependency>
And, as before, the docs will be accessible at:
http://localhost:8080/swagger-ui.html
Here again, we could add the springdoc.swagger-ui.path property in the application.properties file to customize the path.
5. Using springdoc-openapi Maven Plugin
The springdoc-openapi library provides a Maven plugin springdoc-openapi-maven-plugin for generating OpenAPI descriptions in json and yaml formats.
The springdoc-openapi-maven-plugin plugin works with the spring-boot-maven plugin. Maven runs the openapi plugin during the integration-test phase.
Let’s see how we can configure the plugin in our pom.xml:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.8.RELEASE</version>
<executions>
<execution>
<id>pre-integration-test</id>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>post-integration-test</id>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-maven-plugin</artifactId>
<version>0.2</version>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
Also, we can configure the plugin to use custom values:
<plugin>
<executions>
.........
</executions>
<configuration>
<apiDocsUrl>http://localhost:8080/v3/api-docs</apiDocsUrl>
<outputFileName>openapi.json</outputFileName>
<outputDir>${project.build.directory}</outputDir>
</configuration>
</plugin>
Let’s take a closer look at the parameters that we can configure for the plugin:
-
apiDocsUrl – URL where the docs can be accessed in json format, with a default of http://localhost:8080/v3/api-docs
-
outputFileName – Name of the file where the definitions are stored, defaults to openapi.json
-
outputDir – Absolute path for the directory where the docs are stored – by default, $\{project.build.directory}
6. Automatic Document Generation Using JSR-303 Bean Validation
When our model includes JSR-303 bean validation annotations, such as @NotNull, @NotBlank, @Size, @Min, and @Max, the springdoc-openapi library uses them to generate additional schema documentation for the corresponding constraints.
Let’s see an example using our Book bean:
public class Book {
private long id;
@NotBlank
@Size(min = 0, max = 20)
private String title;
@NotBlank
@Size(min = 0, max = 30)
private String author;
}
7. Generate Documentation Using @ControllerAdvice and @ResponseStatus
Using @ResponseStatus on methods in a @RestControllerAdvice class will automatically generate documentation for the response codes. In this @RestControllerAdvice class, the two methods are annotated with @ResponseStatus:
@RestControllerAdvice
public class GlobalControllerExceptionHandler {
@ExceptionHandler(ConversionFailedException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseEntity<String> handleConnversion(RuntimeException ex) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(BookNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ResponseEntity<String> handleBookNotFound(RuntimeException ex) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
}
}
8. Conclusion
In this article, we learned to set up springdoc-openapi in our projects. Then, we saw how to integrate springdoc-openapi with the Swagger UI. We also saw how to do this with Spring Webflux projects.
Next, we used the springdoc-openapi Maven Plugin to generate OpenAPI definitions for our APIs. Finally, we looked at how springdoc-openapi generates documentation automatically using JSR 303 bean validation annotations and the @ResponseStatus annotations in @ControllerAdvice class.
The springdoc-openapi generates API documentation as per OpenAPI 3 specification. It handles the Swagger UI configuration for us, making API document generation a fairly simple task.
As always, the code is available over on GitHub.