Documenting REST API’s

Documenting REST API's with swagger and spring-boot.
Reading Time: 5 minutes

Hi all, in this blog we will see how to document Rest API’s. Documenting the REST API’s is as important as their creation. We should always pay some attention to their documentation. Let’s see why, and how to do that.

Before we move on let’s see the tools we will be using. We will use Spring-boot(v-2.2.x) as our API creation framework, and Swagger to generate the documentation. We will see how spring-boot and swagger can be integrated. We’ll also learn to modify the auto-generated swagger documentation. As a result, at the end of this blog we will have a proper understanding of importance of documentation.

So, let’s get started.

What is REST?

REST(Representational State Transfer) is a web service’s API. It is an architectural style of communication which is lightweight. It uses URI(Uniform Resource Identifier) and HTTP protocols for communication. JSON is the common choice of data format but we can use XML as well. REST API’s facilitate client server communications and architectures. There is a round trip involved between the client and server, where payload exchange occurs. With REST we can mark the data as cache-able, browser can cache such data internally. As a result, unnecessary calls to the back-end are skipped, and data from the cache is served.

Need For Documentation

If you are familiar with SOAP based web services, you already know the wsdl file that described the functionality of the service. WSDL(Web Service Description Language) is an Xml based definition language. The Wsdl file acts as a contract between the provider and the consumer of the service. With Rest APIs we do not have a WSDL file that can enforce a contract as in SOAP. Then how can we make sure that our customers understand how to consume our API? An API consumer, should not have doubt(s) regarding how to use our API, what is the Input and Output of the API? This is where the swagger documentation comes into picture. With REST the common message exchange format is JSON. We can configure Swagger as a common tool for REST API documentation in our spring boot application.

Integrating Swagger

There is support provided for both the reactive and non-reactive API documentation. For a non-reactive API all we need to do is to add these two dependencies in our pom.xml.

<!--Dependencies for Swagger documentation and swagger UI-->
    <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger2</artifactId>
      <version>2.6.1</version>
    </dependency>

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

In case we are building a reactive API then we need to add few more dependencies along with a repository to our code:

<!--Dependencies for Swagger documentation and swagger UI-->
    <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>

    <!--Not required if you are building a non-reactive API-->
    <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-spring-webflux</artifactId>
      <version>3.0.0-SNAPSHOT</version>
    </dependency>

<repositories>
    <repository>
      <id>spring-libs-milestone</id>
      <name>Spring Milestone Maven Repository</name>
      <url>http://oss.jfrog.org/artifactory/oss-snapshot-local/</url>
    </repository>
  </repositories>

Once we have the required dependencies in place, we need to provide a configuration class for Swagger to take effect.

@Configuration
@EnableSwagger2WebFlux
public class SwaggerConfigurationProvider {
    
    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2);
    }
}

We are importing @EnableSwagger2WebFlux because we are developing reactive API using spring webflux. In case you want to build non-reactive API simply import @EnableSwagger2. The numeral `2` in the imports signifies that we are using swagger v 2.0 as our documentation model. In our configuration file we need to provide a Docket bean. A Docket is your primary interface to swagger body. `DocumentationType.SWAGGER_2` creates a new DocumentationType(“swagger”, “2.0”) so that swagger 2 documentation is generated for our API.

Documenting REST API’s

Yes, that’s all you need to do. Just run your application using the normal mvn spring-boot:run command and you can see your Swagger documentation and UI.

API docs are available at: localhost:<your-service-port>/v2/api-docs & Swagger UI is visible at: localhost:<your-service-port>/swagger-ui.html.

In my case my service is running at port 9000, so when i hit the url for swagger doc: localhost:9000/v2/api-docs it gives me:

Swagger documentation generated in postman app. Documenting REST API's.
swagger documentation.

and the UI part would look like:

Swagger UI for the Rest API 's Documentation.
swagger UI.

In the UI we can clearly see that we have created a controller: blog-controller. It exposes a REST endpoint for /getBlogs (GET:/edu/blogs/{blogId}). On clicking the drop down we can also try out our APIs. In my case, i have passed 4 as blogId and this is the response i got from API:

 Documenting REST API's. UI components description in the API's Documentation.
BlogId response from API.

That’s all. We have created documentation for our API. We can clearly see in the screenshot above that the documentation contains the in and out of our API. It also provides a way for the consumer to test your APIs, to become familiar with them and understand their usage.

Improving the documentation

Till now, we have seen how to integrate swagger in our spring-boot service. The auto generated swagger configuration is not that much descriptive. We need to modify it to make it more consumer friendly, let’s see how we can do that.

Remember, the Docket() in swagger configuration class? That is not just an interface to our swagger implementation but is also the key to modify the existing swagger documentation. With Docket we can improve the default swagger documentation. Let’s see how we can do that.

In the UI, the content above blog-controller is not much informative or helpful to a consumer. Let’s enrich it first. We have a .apiInfo(ApiInfo apiInfo) method in Docket.java class that sets the meta information of our API. In the ApiInfo constructor, we can provide the details of our API contact person(s). As a result, our consumers can reach out to the contact person(s) directly. There are other methods as well, like .host(), .produces(), .consumes() etc. With host() we can set the default base url of our API, in our case that is /edu. The produces() and consumes() methods define the input and output of our API. It can be application/json or application/text etc. Let’s update the Docket configuration and see the changes in the swagger UI.

@Configuration
@EnableSwagger2WebFlux
public class SwaggerConfigurationProvider {
    
    private static final String TITLE = "Educational Content";
    private static final String DESCRIPTION = "This blog provides insight on how to integrate swagger docs to your spring web flux services.";
    private static final String VERSION = "V1.0";
    private static final String TERMS_OF_SERVICE_URL = "N/A";
    private static final Contact CONTACT = new Contact("Prashant_Sharma", "https://blog.knoldus.com/?s=prashant",
            "prashant.sharma@knoldus.com");
    private static final String LICENSE = "Apache 2.0";
    private static final String LICENSE_URL = "http://www.apache.org/licenses/LICENSE-2.0";
    private static final Set<String> PRODUCES = new HashSet<>(Arrays.asList("application/json", "application/text"));
    private static final Set<String> CONSUMES = new HashSet<>(Arrays.asList("application/json", "application/text"));
    
    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(new ApiInfo(TITLE, DESCRIPTION, VERSION, TERMS_OF_SERVICE_URL, CONTACT, LICENSE,
                        LICENSE_URL, new ArrayList<>()))
                .host("localhost:9000/edu")
                .produces(PRODUCES)
                .consumes(CONSUMES);
    }
}

On the UI/docs part we will see the changes made to the documentation:

A much more descriptive and useful swagger UI for our API's consumers.  Documenting REST API's.
Descriptive UI.
Documenting REST API's with useful information from a consumer's perspective.
Useful links and maps in documentation.

That is all for now. I hope you like this blog, and are able to understand the need for documentation of our APIs. Please feel free to add your queries in the comments section below. Spread the love for APIs and documentation. 🙂

References:


Knoldus-blog-footer-image

Written by 

Prashant is a Senior Software Consultant having experience of more than 3 years, both in service development and client interaction. He is familiar with Object Oriented Programming Paradigms and has worked upon Java and Scala-based technologies and has experience working with the reactive technology stack, following the agile methodology. He's currently involved in creating reactive microservices some of which are already live and running successfully in production, he has also worked upon scaling of these microservices by implementing the best practices of APIGEE-Edge. He is a good team player, and currently managing a team of 4 people. He's always eager to learn new and advance concepts in order to expand his horizon and apply them in project development with his skills. His hobbies include Teaching, Playing Sports, Cooking, watching Sci-Fi movies and traveling with friends.