Document Spring Boot RESTful API With Swagger-2.0

unsplash-logoPuttipol Waipanya

Now Days Spring Boot is de facto standard for developing RESTful services.Spring Boot makes it very easy to build RESTful services.In SOAP based web services, you had a WSDL which works as documentation for your API. For Rest Services we do not have WSDL so documentation of API becomes more critical.

Swagger

Swagger 2 is an open source framework used to describe and document RESTful APIs.Swagger Can read your API’s structure and automatically build beautiful and interactive API documentation. Swagger makes documenting your RESTful services easy.
Check Docs for all Features.

The code for this post is available for download here.

Swagger + Spring Boot

Swagger Can easily integrate with Spring Boot. To Integrate Swagger we need to use Swagger UI & SpringFox.

Maven Dependency
1
2
3
4
5
6
7
8
9
10
11
   <dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>

Demo Spring Boot RESTful Application

let’s Create documentation for our Demo Spring Boot RESTful Application. Demo Application expose User rest endpoint that allows to perform CURD operations for User.

User Endpoint
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
   @GetMapping
public List<User> getAllUsers() {
return userservice.getAllUsers();
}
@GetMapping("/{id}")
public User getUser(@PathVariable int id) {
return userservice.getUser(id);
}
@PostMapping
public ResponseEntity addUser(@RequestBody User user) {
userservice.addUser(user);
return new ResponseEntity("User Added successfully", HttpStatus.OK);
}
@PutMapping
public ResponseEntity updateUser(@RequestBody User user) {
userservice.updateUser(user);
return new ResponseEntity("User Updated successfully", HttpStatus.OK);
}
@DeleteMapping("/{id}")
public ResponseEntity deleteUser(@PathVariable int id) {
userservice.deleteUser(id);
return new ResponseEntity("User Deleted successfully", HttpStatus.OK);
}

Swagger Configuration

We need to create a Docket bean in a Spring Boot configuration to configure Swagger 2. A Springfox Docket instance provides the primary API configuration with sensible defaults and convenience methods for configuration.
@EnableSwagger2 Indicates that Swagger support should be enabled. This should be applied to a Spring java config and should have an accompanying @Configuration annotation. Loads all required beans defined in @SpringSwaggerConfig

Below is minimum configuration required for Swagger.

SwaggerConfig
1
2
3
4
5
6
7
8
9
10
11
12
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
}

Now If we run the application and go to http://localhost:8080/swagger-ui.html documentation will be rendered by Swagger UI.

Update Swagger Configuration for Customization - ApInfo

ApiInfo
1
2
3
4
5
6
7
8
9
10
11
private ApiInfo apinfo() {
return new ApiInfoBuilder()
.title("User Management API")
.description("Rest API to Perfrom CURD ")
.termsOfServiceUrl("Some Terms of Services URL")
.version("1.0.0")
.license("Some License Info")
.licenseUrl("Some License URL")
.contact(new Contact("Niraj Sonawane", "https://nirajsonawane.github.io/","Niraj.Sonawane@gmail.com"))
.build();
}

Update Swagger Configuration for Customization - Selecting Specific Endpoints

When we verify the Generated documentation, We see that in Basic Error Controller along with our User Controller and Model.
We can Configure Swagger to generated documentation only for certain endpoints using RequestHandlerSelectors.

The Available options for Configurations are

  1. RequestHandlerSelectors.basePackage(basePackage)
  2. RequestHandlerSelectors.withClassAnnotation(annotation)
  3. RequestHandlerSelectors.withMethodAnnotation(annotation)

Swagger Annotations On Controller classes

Swagger provides annotations that can be applied on Controller classes to provide additional information,
We can annotate controllers and their methods and method parameters.

  • @Api describes the whole controller
  • @ApiOperation is used for description on a methods level
  • @ApiResponses is used for description of response codes on a methods level
  • @ApiParam is used for method parameters
Swagger Annotations On Controller classes
1
2
3
4
5
6
7
8
9
10
11
@GetMapping("/{id}")
@ApiOperation(consumes="application/json", produces="application/json",protocols="http", value = "getUser" )
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Successfully retrieved User"),
@ApiResponse(code = 401, message = "The request has not been applied because it lacks valid authentication credentials for the target resource"),
@ApiResponse(code = 403, message = "The server understood the request but refuses to authorize it"),
@ApiResponse(code = 404, message = "The resource not found")
})
public User getUser(@ApiParam("Id of user, Can not be null") @PathVariable int id) {
return userservice.getUser(id);
}

Swagger Annotations On Model classes

Swagger Core annotations, Can be used to specify additional information about your model Class.
e.g User Class annotated with these annotations can look something like this

Swagger Annotations On Model classes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

@ApiModel(description = "Class representing User ")
public class User {

@ApiModelProperty(notes = "Unique ID for user", example = "1", required = true, position = 0)
private int id;

@ApiModelProperty(notes = "First Name of User", example = "Niraj", required = true, position = 1)
private String firstName;

@ApiModelProperty(notes = "Last Name of User", example = "Sonawane", required = true, position = 2)
private String lastName;

@ApiModelProperty(notes = "Middle Name of User", example = "Ashok", required = false, position = 3)
private String middleName;

@ApiModelProperty(notes = "Age of User", example = "32", required = true, position = 4)
private Integer age;
}

Swagger Integration with JSR-303 Annotations

JSR 303 Bean Validation is the specification of the Java API for JavaBean validation in Java EE and Java SE. This is very popular mechanism for validation and number of projects are using it.

JSR 303 Bean Validation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Data
public class User {
private int id;
@NotBlank
@Size(min = 2, max = 10)
private String firstName;

@NotBlank
private String lastName;

private String middleName;
@NotNull
@Min(2)
@Max(100)
private Integer age;
}

This is a common practice which is already widely used. Swagger can be easily configured to read these annotations and generate documentation based on such annotations.
This makes Swagger very useful as we can utilize what we already have in our project without writing all the constraints manually. Consumers also know what are restrictions on the values and what they should provide to API and what values to expect.

Add dependency in pom file
1
2
3
4
5
      <dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-bean-validators</artifactId>
<version>2.9.2</version>
</dependency>
Import BeanValidatorPluginsConfiguration
1
2
3
4
5
 
@Configuration
@EnableSwagger2
@Import(BeanValidatorPluginsConfiguration.class)
public class SwaggerConfig {

After Integration Model will look like below in generated documentation.

The code for this post is available for download here.

Share Comments