If you are a back-end developer, you probably work with APIs a lot. And you're probably aware of how API documentations can take forever to write, but are essential for communication between teams and for users to be able to use your API.
In this article, I want to introduce you to Swagger, an ecosystem of useful products and tools for easy API development and documentation with OpenAPI Specification (OAS). We will particularly focus on the product Swagger Editor to generate an API documentation easily for an existing API.
What is OAS?
OAS or Open API Specification defines the blueprint of an API in a human-readable manner. This means that anyone can take a look at your OAS documentation and will be able to understand what the API can do.
Swagger streamline REST API documenting with its tools. Using Swagger Editor, we can easily edit and generate an interactive documentation like the example below:
Source: petstore.swagger.io
Why OAS?
A great benefit of this type of API documentation is that users can easily test the API without having to integrate it into an app themselves. It makes it more convenient for companies or developers to showcase their APIs and grow their products.
This survey shows that accurate and good documentation is the top reasons of consumers to use an API.
Create an API Documentation
Now that we learned the great things about using Swagger, let's try out one of their products, Swagger Editor, to create an API documentation!
You can easily access this tool online at: editor.swagger.io.
1. Header
It's easy to construct a simple header for your API documentation. It should include information like:
API name + description + version
Base URL
License
Important Links (if any)
Schemes (http or https)
Here's an example of the header of an API I built.
Swagger Editor allows YAML or JSON format. It will immediately generate the documentation accordingly. So for our header, we can write this block of JSON to generate one like my example:
{
"swagger": "2.0",
"info": {
"description": "This is the API for Overstrategize. Inspired from [https://www.heropicker.com/](https://www.heropicker.com/).",
"version": "0.1.0",
"title": "Overstrategize API",
"contact": {
"email": "victoria-lo@hotmail.com"
},
"license": {
"name": "MIT License",
"url": "https://github.com/victoria-lo/overstrategize/blob/master/README.md"
}
},
"host": "localhost:5500",
"basePath": "/",
"externalDocs": {
"description": "Learn more about Overstrategize",
"url": "https://localhost:5500"
},
"schemes": [
"https",
"http"
],
// ...
}
2. Tags
Next, we can add the most important part of our API documentation, the routes or endpoints.
Before we add routes, we can create categories for them. These are called tags. They will sit below your header and you can categorize routes based on tags to keep your documentation look organized. In my example, I have a hero
and map
category:
To generate tags on your documentation, simply add the tags
array in the Swagger Editor.
// Header above
"tags": [
{
"name": "hero",
"description": "Hero information"
},
{
"name": "map",
"description": "Map information"
}
],
// ...
3. Routes and Definitions
Let's make our first route under the hero tag. We want this route /hero
to GET all hero data as objects in an array. The result should generate our documentation like below:
This documentation clearly describes everything we need to know about this route. It has no parameters, returns a JSON array with the properties name
and description
for each hero.
How do we clearly define the properties of each hero object and display it in our documentation like the image above? We can use definitions.
Start by adding the paths
and definitions
properties below our tags
array.
// tags above
"paths": {
//all routes in here
},
"definitions": {
//all definitions in here
}
Now let's create a Hero object with a name
and description
property. We will add it under definitions
:
"definitions": {
// define Hero
"Hero": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "name of hero"
},
"description": {
"type": "string",
"description": "description of hero"
}
}
}
}
Great! Now we can refer to this object in our GET /hero route as the returned data. Let's write our route under paths
as shown below:
"paths": {
"/hero": {
"get": { //specify the http method
"tags": [
"hero" //specify the tag this route belongs to
],
"summary": "Gets all hero data",
"description": "Gets all hero data",
"operationId": "getHeroes",
"produces": [
"application/json" //return data format
],
"responses": {
"200": { //status code
"description": "OK",
"schema": {
"type": "array", //data being returned is an array of objects
"items": {
"$ref": "#/definitions/Hero" //refers to the Hero object we defined earlier
}
}
}
}
}
}
}
As you can see, most of the properties included in a route are pretty self-explanatory. We want our documentation to be able to show an example data being returned on a successful GET request, so we include it under responses
> 200
> schema
. We then refer to our Hero object under definitions
using "$ref": "#/definitions/Hero"
.
And the Swagger Editor will generate the documentation for the route based on this JSON. A definition will appear in the documentation under Models. Pretty neat, isn't it?
This structure makes the documentation organized and easy to understand even for those who have never used your API before.
4. Routes with Parameters
Let's take it to next level. How about generating documentation for a route that accepts parameters? For example, to get only one hero object from its name, we should have a /hero/{name} route.
With parameters, the route needs to have a parameters
array that contains parameter objects. Each object represents a parameter and must include properties such as:
name
: name of paramin
: location of param (i.e. body or path)required
: true or falsetype
: i.e. string, int, boolean
Our /hero/{name} route will be written as follows:
//add this below the first route
"/hero/{name}": {
"get": {
"tags": [
"hero"
],
"summary": "Gets hero data by name",
"description": "Gets hero data by name",
"operationId": "getHeroByName",
"produces": [
"application/json"
],
//add the params array
"parameters": [
{
"name": "name",
"in": "path", //param name is in the path itself
"description": "Name of hero to return",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/Hero" //returns just the Hero object, not an array
}
}
}
}
}
As seen above, the main differences between this route and the /hero is the route name, parameters and schema. In this route, the schema only returns the Hero object itself because it only returns ONE Hero object, not an array of objects.
And the result will be a wonderfully generated route. Users can even test the route by supplying a name in the name parameter field.
The interactive feature of this type of documentation is very useful for other developers to test and use your API without having to build an app or set up POSTman. It's quicker and easier to use. And it's all generated by just a JSON!
Viewing your API
After you're done with writing your JSON on Swagger Editor, you can download the file or store it somewhere.
Download by clicking File > Save As JSON.
For instance, I have uploaded my example API's JSON file to Google Cloud Storage. If you head to petstore.swagger.io and paste the URL of the JSON file, you can view the API documentation.
Integrating in an app
What if you want to show your API documentation not by pasting it to the Swagger website? Instead, you want it in your own app as its own page? I'll briefly explain 2 examples on how you can do that.
Adding to an Express app
After downloading your JSON file from the Swagger Editor, import it in your app's folder. Then install this package:
npm install swagger-ui-express
In your Express app, locate your server.js
(or the file where the app
is) to import the package you just installed and the JSON file. Then, setup the route where your documentation will be served on.
Here's what it looks like in code:
const swaggerUi = require('swagger-ui-express');
const swaggerDocument = require('./swagger.json');
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
More details can be found at npmjs.com/package/swagger-ui-express.
Adding to a React app
For a React app, you can install this package with the command:
npm install swagger-ui-react
Then, create new component like Docs.js
for example and add this code inside:
import SwaggerUI from "swagger-ui-react"
import "swagger-ui-react/swagger-ui.css"
function Docs(){
return (
<SwaggerUI url="https://storage.googleapis.com/overstrategize-viclo/overstrategize.json" />
)
}
export default Docs;
The url
prop must be a remote URL so it cannot be from localhost. It must be available online.
Learn more at npmjs.com/package/swagger-ui-react.
Conclusion
There's plenty of tools out there to help generate well-structured and easy-to-use API documentations. The Swagger Editor is one of them, a powerful yet simple tool to generate incredibly informative, detailed and interactive API documentations.
Thanks for reading! I hope it has been helpful in getting anyone started with writing excellent documentation for their APIs. If you find it helpful in any way, please like and share this article around for more reach. Also, please feel free to comment or ask questions below. Till next time, cheers!