Document your Already Existing APIs with Swagger

Documenting an already Existing API with Swagger

We recently covered speeding your restful api development with Swagger. The article is really clear on how to use swagger, and I would suggest you read it first before going through this.

The article however starts with an API from scratch. But this may not be the case for some of us. I, for instance had an API that was already in existense. If you were wondering how to leverage Swagger for your already built and hosted API, brace yourself for a short but intersting quick tip read.

Swagger UI

Swagger UI is the beautiful view we see when we document our api with swagger. The readme of the project defines it this way:

Swagger UI is a dependency-free collection of HTML, Javascript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API. http://swagger.io

We can use Swagger UI in one of two ways:

  1. AS IS : This involves just copying the content of the dist folder and editing the source of the configuration file. (either .yaml or .json)
  2. Build : This involves cloning the Swagger UI repo, making a few tweaks based on your preferences and doing your own build. It will generate a dist folder, which you can then continue to use editing a config file.

We'll take the latter approach to document a small API. Since this is a quick tip article, we'll document three routes for the Open Github API, trying to cusomize it as much as possible

Setup

Clone the Swagger UI repo and install the dependecies.

# Clone the repo
$ git clone https://github.com/swagger-api/swagger-ui.git

# cd into the folder
$ cd swagger-ui

# Install dependecies
$ npm install

# install gulp globally
$ npm install -g gulp

# Build Swagger
$ gulp build

While there is already a dist directory, build deletes everything and recreates the dist directory every time you run it.

Open the dist/index.html file in your browser, or better yet, serve the dist folder with httpster.

# install httpster
$ npm install -g httpster

# serve the dist folder
$ httpster -d dist

Open http://localhost:3333 to see the default swagger ui display Default Swagger Configuration

Customizing Swagger

If you are good in CSS, you can do quite some customization for Swagger. I'll do two quick customizations just to show this.

The default swagger header background color is green. Since we are documenting the Open github api, it would be nice to change it to black.

Look for the header style in the screen.less file

src/main/less/screen.less

#header {
    background-color: #89bf04;
    padding: 9px 14px 19px 14px;
    height: 23px;
    min-width: 775px;
  }

And simply change the color to black.

#header {
    background-color: black;
    padding: 9px 14px 19px 14px;
    height: 23px;
    min-width: 775px;
  }

Next, we'll change the title and the logo to reflect use the gitub logo. I did a quick google search for a github logo, and added the url directly to the src attribute of it's img tag.

src/main/html/index.html

<!DOCTYPE html>
<html>
<head>
<!-- Markup commented out for brevity-->
    <title>GITHUB API</title>
<!-- Markup commented out for brevity -->
</head>
<body class="swagger-section">
     <div id='header'>
          <div class="swagger-ui-wrap">
            <a id="logo" href="http://swagger.io">
                <!-- We change the Logo displayed here in the src property -->
                <img class="logo__img" alt="swagger" height="30" width="30" src="http://www.lpl-aix.fr/~bigi/etc/icons/github.png" />
                <span class="logo__title">Github API</span></a>
                <!-- Markup Commented out for brevity-->
          </div>
        </div>
</body>
</html>

Configuring our Swagger API file

Before we look at the results of the customization, let's quickly create our configuration file. Create a new file called github.json in src/main/ directory.

NOTE: This file can either be a .json file or a .yaml file. It's what swagger reads to interpret your API. Yaml file has a different syntax however.

src/main/github.json

{
  "swagger": "2.0",
  "info": {
    "description": "This is a sample documentation for the open github api. The api is located at https://api.github.com/",
    "version": "0.0.1",
    "title": "Github API",
    "contact": {
      "email": "john.doe@gmail.com"
    },
    "license": {
      "name": "MIT",
      "url": "https://github.com/swagger-api/swagger-ui/blob/master/LICENSE"
    }
  },
  "host": "api.github.com",
  "basePath": "/",
  "produces": ["application/json"],
  "schemes": [
    "https"
  ]
}

NOTE: The key things here are the host and schemes properties. They should show where your api is hosted.

Finally, let's change the loaded configuration file from swagger's default to our github json.

src/main/index.html

<!DOCTYPE html>
<html>
<head>
    <!-- Markup commented out for brevity-->
    <script type="text/javascript">
        $(function () {
          var url = window.location.search.match(/url=([^&]+)/);
          if (url && url.length > 1) {
            url = decodeURIComponent(url[1]);
          } else {
            // Use our custom configuration file
            url = '/github.json';
          }
        // JS code commented out for brevity
        });
    </script>
</head>
<!-- Markup commented out for brevity -->
</html>

Notice the line url = '/github.json' in the else block. That will load our Github json Swagger config file.

Build swagger and run httpster.

$ npm run build
$ httpster -d dist

Open locahost:3333 Github API Swagger

Documenting the Routes

We'll document two routes:

  1. GET / - Get infomation about the github API
  2. GET /users - Get a list of github users
  3. GET /users/:username - Get a specific github user when username is provided

GET /

Let's edit the github.json file.

src/main/github.json

{
  ....,
  "schemes": ["https"],
  "paths": {
    "/": {
      "get": {
        "tags": ["info"],
        "description": "Get information about the Github API",
        "responses": {
          "200": {
            "description": "successfully got info",
            "schema": {
              "type": "object",
              "properties": {
                "current_user_url": {
                  "type": "string"
                },
                "authorizations_url": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  }
}

I won't go much into the details of the path properties, as Sam had covered them already here. You could also read more about the spec here.

But notice my response schema is in-line, I haven't referenced it anywhere, and I have an example object. We can do a build and open the ui with httpster.

Swagger GET /

When you click on try it out, the api will be called, and you will see the results below the button.

GET /users

This path returns about 30 users from the github API. We'll quickly add it's configuration to the config file.

Assuming your httpster server is still running, we can edit the github.json file direclty without a rebuild.

dist/github.json

{
    ...,
    "paths": {
        ...,
        "/users": {
          "get": {
            "tags": ["Users"],
            "description": "Get list of users from github",
            "responses": {
                  "200": {
                    "description": "Successfully got users",
                    "schema": {
                          "type": "array",
                          "items": [{}]
                    }
                  }
            }
          }
        }
    }
}

I've left the items property empty, but ideally you could fill in an array of objects based on github's response, or your API's response.

Refreshing the browser should give this. GET /users github Once again, you can click on the try it out button, and it should return a response from the API.

GET /users/:username

Our final route to document is getting a user by the username. Let's add this to the github.json file.

dist/github.json

 {
    ...,
    "paths": {
        ...,
        "/users/{username}": {
              "get": {
                "tags": [
                    "Users"
                ],
                "description": "Get a github user by passing in their username",
                "parameters": [
                    {
                        "name": "username",
                        "in": "path",
                        "description": "The github username of the user",
                        "required": true,
                        "type": "string"
                      }
                ],
                "responses": {
                     "200": {
                        "description": "Successfully got github user",
                        "schema": {
                              "type": "object",
                              "properties": {
                                "login": {
                                     "type": "string"
                                }
                              }
                        }
                     }
                }
            }
        }
    }
}

This time round we have a parameter, username, and we've included it in our json properties.

Refreshing the page should display GET /users/{username} swagger

Put in a username you are know about, like scotch and click on try it now. You should see the details of the Github user below the button.

Conclusions

We've seen how to document an already existing API. If you look closesly, all it entails is editing a config file that is either json or yaml.

Swagger UI is also easily customizable, which means you can tune it to your liking and even theme your API documentation based on a predefined scheme, or preference.

What's left now is to just study the Specifications for the config file and you are good to go.

Ganga Chris

I'm a Full Stack Developer (Mostly JavaScript, PHP & Go).