Build Interactive API Documentations Easily with Swagger

Build Interactive API Documentations Easily with Swagger

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.

image.png

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:

1.gif

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.

image.png

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.

image.png

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:

image.png

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:

image.png

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?

image.png

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 param

  • in: location of param (i.e. body or path)

  • required: true or false

  • type: 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.

image.png

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.

save.gif

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.

test.gif

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!


References

Did you find this article valuable?

Support Victoria Lo by becoming a sponsor. Any amount is appreciated!

ย