Documenting a Spring Boot CRUD RESTful API/Web Service with Swagger

Overview

In a previous article, which you can check here, we started the development of a simple users API using Spring boot. We recommend it to be read before continuing with this article.

Spring Boot is a powerful tool when creating a RESTful web service and Swagger is a powerful tool when documenting a RESTful web service, which can also be used for quick testing the API.

When building a back-end API layer, it’s necessary to also think about the users that’ll be interacting with the API, thus the point of documentation.

A good documentation should have a informative structure and should be easy to read. This article will focus on implementing and setting up Swagger to provide our service with such characteristics.

It is also possible to do the other way around, and create an API starting from an Open API specification. But we will cover that in another post.

Quick demo

An example of what we should aim to build is the Petstore that was generated using Swagger UI.

There are 3 endpoints group categories, each with a set of operations described in a simple and easy to understand way :

Also, we’re able to verify the flow of the API by going through the endpoints and this is essentially what we should aim to do with our implementation.

Getting started

Our first step should be adding the following Springfox implementations of Swagger to our maven pom.xml file in the API project folder.

<dependency>
  <groupId>io.springfox</groupId>
  <artifactId>springfox-swagger2</artifactId>
  <version>3.0.0-SNAPSHOT</version>
</dependency>

<dependency>
  <groupId>io.springfox</groupId>
  <artifactId>springfox-swagger-ui</artifactId>
  <version>3.0.0-SNAPSHOT</version>
</dependency>

<dependency>
  <groupId>io.springfox</groupId>
  <artifactId>springfox-data-rest</artifactId>
  <version>3.0.0-SNAPSHOT</version>
</dependency>

Configuring Swagger into our API

Coding-wise we should begin by creating a configuration class for Swagger and adding our Docket bean which will be the core of all implementation specifics.

We’re implementing WebMvcConfigurer in our class to eventually configure the resource handlers that’ll be added through the Swagger UI dependency.

src/main/java/com/usersapi/swagger/SpringFoxConfiguration.java

@Configuration
@EnableSwagger2WebMvc
@EnableWebMvc
public class SpringFoxConfiguration implements WebMvcConfigurer {

    @Bean
    public Docket productApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.usersapi"))
                .paths(PathSelectors.any())
                .build();
    }
}

Implementing resource handlers

In our SpringFoxConfiguration class, we need to implement resource handlers with the @Override annotation to specify that this should override any standard configuration from Spring :

src/main/java/com/usersapi/swagger/SpringFoxConfiguration.java

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("swagger-ui.html")
      .addResourceLocations("classpath:/META-INF/resources/");
 
    registry.addResourceHandler("/webjars/**")
      .addResourceLocations("classpath:/META-INF/resources/webjars/");
} 

Adding custom information to our user interface

Adding the apiInfo method to our Docket bean should provide us with the possibility of creating a customInfo class with our custom info :

src/main/java/com/usersapi/swagger/SpringFoxConfiguration.java

@Bean
public Docket productApi() {
    return new Docket(DocumentationType.SWAGGER_2)
            .select()
            .apis(RequestHandlerSelectors.basePackage("com.usersapi"))
            .paths(PathSelectors.any())
            .build()
            .apiInfo(customInfo());
}

private ApiInfo customInfo() {

    ApiInfo customInfo = new ApiInfo(
            "Users API",
            "CodeFiction Project",
            "2.0",
            "Terms of service",
            new Contact("Gabriel Pulga", "www.codefiction.net", "[email protected]"),
            "API license",
            "API license URL",
            Collections.emptyList());

    return customInfo;
}

If we visit our localhost page at http://localhost:8080/swagger-ui.html, we’re able to verify that Swagger is already up and running with each of our endpoints listed in the web page.

Endpoint documentation

For each endpoint controller we’ll need to describe its functionality through the @Api and @ApiOperation annotations, so for instance, our DeleteUserController should be :

src/main/java/com/usersapi/endpoints/delete/DeleteUserController.java

@RestController
@RequestMapping("/users/{id}")
@Api(tags = "Delete an existing user with the DELETE method")
public class DeleteUserController {

    @Autowired
    DeleteUserService service;

    @DeleteMapping
    @ResponseStatus(HttpStatus.NO_CONTENT)
    @ApiOperation(value = "Execute DELETE method")
    public void deleteUser_whenDeleteUser(@PathVariable Long id) {
        service.deleteUser(id);
    }
}
Swagger interface with documented endpoints

Endnotes

Throughout this tutorial you learned how to implement Swagger in a Spring Boot RESTful API and describe each of your endpoints functionalities by creating custom descriptions with the purpose of making a friendlier user interface.

Next possible steps for developing our API will be :

  • Unit testing our endpoints controllers and services with JUnit and Mockito.
  • Integration testing our whole API.

Source code

Available in our github page.

Thanks for reading !! Feel free to leave any comment.

About the author

Website | + Posts

Software Consultant with more than 11 years experience, most of that in Finance area. I love building things and see them running and making a difference.

Specialised in Golang (2 years), Java (11 years), Javascript, React and Angular (1 year), PHP (2 years), project management and delivery leading (2 years), mentoring and coaching (1 year).

Website | + Posts

Electrical engineering student from Brazil passionate about learning and teaching people.

Had some professional and academic engineering experiences, now my focus is on studying and developing software as a full time job.

Leave a Reply

Your email address will not be published. Required fields are marked *