RESTful API Documentation Made Easy with Swagger and OpenAPI
Swagger and OpenAPI specification lets us design and develop REST APIs in an effortless and seamless manner. These specifications allow describing the structure of an entire REST API so that machines can read and mock them. This article provides a comprehensive guide to these concepts with an end to end example of all major Swagger components.
Over the last few years, RESTful web services have drawn a considerable amount of attention and became the de-facto standard in the web services ecosystem. It has not only out spaced its complex counterpart — SOAP but also has become the default choice in API design and development.
An API is essentially a contract. A contract that both the API publisher and its consumers are agreed to adhere to in order to effectively communicate. And like most other contracts, to work in an expected manner, an API should document its various aspects. Aspects such as the endpoints it offers, operations that the endpoints support, the signature an operation understand and the response it returns for a request? Moreover, to accommodate ever-changing demands, an API evolves over time. In such a scenario, well documenting an API is not a choice but an integral part of its offerings to ensure a better customer experience.
But how do we document our APIs? How do we define the set of components that should be part of a well-documented API? In addition, we kept on updating our service offerings and there is a need to maintain multiple versions of these APIs. How do we version API documentation then? One could have an API with hundreds of endpoints. How do we even write the documentation for all these endpoints and their operations? Manually? No way. How do we even ensure our API documentation is understandable to our consumers? is there even a way to standardize API documentation and its generation process?
This article attempts to provide an answer to these aforementioned questions. We will discuss OpenAPI and a tool around OpenAPI — Swagger that helps us in our API documentation and further development based on these APIs.
What is OpenAPI Specification?
OpenAPI Specification (previously known as Swagger Specification) is an API description format for REST APIs. An OpenAPI specification compatible file allows us to describe a complete REST API. It is generally written in YAML or in the JSON file format.
This file let us:-
- Describe all available API endpoints (e.g. /users, /users/{id})
- Operations in the endpoints such as GET /users, POST /user
- Input and Output parameters for each operation
- Authentication mechanisms
- Contact information, API Licence, terms of use and other information
What is Swagger?
Swagger is a set of open-source tools built around the OpenAPI Specification that can help us to design, build, document and consume REST APIs. The ability of APIs to describe their own structure is the root of all awesomeness in Swagger. Note that Swagger not only helps us to design and document REST APIs, it also lets us build (Server Stub) and Consume (Rest Clients) REST APIs.
The major Swagger tools include:
- Swagger Editor — browser-based editor where one can write OpenAPI specification
- Swagger UI — renders OpenAPI specs as interactive API documentation
- Swagger Codegen — generates server stubs and client libraries from an OpenAPI specification
We will talk about the above three tools in detail throughout this article.
Following is a sample OpenAPI document in the Swagger Editor:-
Swagger in Action
Now that we have understood what OpenAPI and Swagger are, let us see these in action. As part of this article, we will develop a REST application. We will then use Swagger UI to render our API documentation. Following that, we access the API document (available in JSON format) through Swagger Editor. Lastly, we will use Swagger Codegen CLI to generate a server and a client stub to demonstrate how one can use an OpenAPI document to mock the REST web services.
What are we building?
We will build a Spring Boot application that offers us to manage blood donors. It allows us to create, update, delete and view donor information.
Refer to this link for a step by step guide on how to set up the application in a development environment. Complete source code can be downloaded from this Github repository.
Following are the summary of steps:-
- Create a new Spring boot application with JPA, H2 and Web dependencies
- Create the model, service and the controllers
- Run the application and try accessing various endpoints & its operations
Below is the application pom file:
We have added the following two additional dependencies from io.springfox to enable Swagger 2 and Swagger UI:-
<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>
Swagger Configuration
Now that the project is up & running and we can access our REST endpoints, let us add the swagger configuration:-
This is a Spring configuration with Swagger documentation information. We have added metadata information about the REST API such as API name, author, website, license and so on. We have also instructed Swagger to only generate documentation for the components present in the io.codefountain.swagger package.
Accessing Swagger UI
Since we have enabled Swagger, let us see the documentation of our API endpoints done by Swagger. This is rendered through Swagger UI in the following link:
http://localhost:8080//swagger-ui.html#/donor-controller
Swagger has put together the following information:-
- Document metadata (API name, license, website, contact and so on)
- All REST endpoints with default information it can infer from code. Note that endpoint descriptions are method names
These are the default information. Let us now explicitly document of our API with swagger annotations to provide a detailed description and information about the endpoints and operations.
Documenting Rest Controller
As discussed, we will now document the REST controller explicitly. Swagger provides several annotations to add documentation metadata that it pulls while generating the documentation.
For each of the REST endpoint and its associated operations, we have provided ApiOperation and their various responses with ApiResponses annotations.
Restart the application and access the same URL:
This time, Swagger has pulled the information supplied through the annotations. Not only this, it has now added explicit response information with HTTP response codes:-
Accessing Swagger Editor
So far we have accessed the API documentation locally. Swagger also generates the documentation in the JSON file format adhering to the OpenAPI specification. We can share this JSON file with the consumers and they can read the endpoint information, generate client and server stubs.
Our REST API documentation can be accessed through the following URL:-
http://localhost:8080/v2/api-docs
This JSON document conforms OpenAPI specification and can be accessed through Swagger Editor as shown below:-
Anyone with access to this document can view the API endpoints and all other related metadata such as model structure, data types and so on.
Stubbing with Swagger Codegen
We have already seen two beautiful tools that Swagger offers to manage document generation and access. The third tool, Swagger codegen lets us generate server stub and client SDKs from a supplied OpenAPI document. Swagger codegen presently supports the following server (Over 20 languages) and client SDK generation (Over 40 languages):-
Swagger codegen can be access through Command Line Interface (codegen-cli) or the maven plugin. In this article, we will use Swagger codegen CLI. To access codegen CLI jar file you can
- Download the jar from here
- Or, if you want the latest changes, browse to Swagger Codegen Github repository and clone it to your local machine. Build the project and browse to swagger-codegen/modules/swagger-codegen-cli/target folder
Generating a Spring boot server stub
We will generate a Server stub from the OpenAPI document. This stub can be used for mocking and testing the endpoints. This is a common scenario when the provider might have shared the API documentation but the consumer does not have access to the provider infrastructure. In such cases, it is absolutely essential to mock the endpoint and operations to simulate the API access.
In this section, we will generate a server stub and implement the GET mapping /api/donors/{id}
To generate the server stub, browse to the location of swagger codegen CLI jar file and run the following command:-
In the above command, we are doing the following:-
- Specifying the location of API specification with the -i argument. Change this location as per the location of your environment
- Specifying the package structures. If this is not provided Swagger will use default io.swagger packages
- Type of the server stub with the -l option
- Finally, the location of the spring boot project with the -o option
Once the command executes, it will generate a spring boot project with all the endpoint stubs. All these stub methods by default return HTTP error code 501 (Not Implemented). You can download the sample stub I have generated for this article from this Github repository.
Following is the updated class:-
This project is configured to run in port 8081. Once we try to access the api/donors/1 endpoint, we receive the following:-
Generating a Node JS server stub
In this section, we will generate a node JS server stub from the API documentation.
This command generates a Node JS application. Open index.js and change the server port 8082. Browse to node/service/DonorControllerService file and edit the getDonorUsingGET function as shown below:-
Execute npm start to start the server:-
Access the API documentation:-
Accessing the /api/donors/1 endpoint:-
Conclusion
Congratulations! If you have managed to reach till here, then you have surely learned a lot. Swagger is an exceptionally powerful tool and opens up a new dimension in the REST API ecosystem. It provides absolute flexibility to automate the API documentation process.