Need help with Swagger-Node-Express-For-Existing-APIs?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

shawngong
126 Stars 41 Forks 40 Commits 4 Opened issues

Description

A comprehensive guide on setting up Swagger-UI for already built APIs.

Services available

!
?

Need anything else?

Contributors list

No Data

EDIT

Updated for newest version of Swagger-Node (2.1.3).

EDIT 2

Please use version 2.X for swagger-ui. This guide is not guarenteed to work on any later versions.

Swagger-Node-Express-For-Existing-APIs

A comprehensive guide on setting up Swagger in already built node-express-APIs.

Introduction

Tired of your poorly documented APIs? Well, luckily for you Swagger provides an open source software that allows for easy RESTful API documentation with the ability to test API endpoints in the UI.

An example can be found here.

However, a lot of the documentation is based around creating Swagger compatable APIs from the ground up. With this guide, you will learn how to configure an existing node API with Swagger.

Contents

Getting Started

Assumptions

For the purpose of this guide we will assume that you have a working knowledge of node.js and express, as well as an existing node API.

The Idea

What we want to do is set up Swagger as a subpath within our existing API (which may or may not already have an UI). Thus, the Swagger routes will not interfere with the routes that already exist within our API.

We will then create a swagger-spec, which is .json file that contains all the information Swagger-UI needs to generate its UI.

Finally, we will set up Swagger-UI with the spec, and make sure the endpoints are being tested properly.

What to Use

We will be using Swagger-Node-Express, minimist, body-parser and Swagger-UI.

Setting up Swagger

We begin by including

swagger-node-express
and
minimist
in our
package.json
dependencies.
{
    ...

"dependencies": {
    "swagger-node-express": "~2.0",
    "minimist": "*",
    "body-parser": "1.9.x",
    ...
}

...

}

Then we install these modules using

npm install

Cloning Swagger-UI

We go to Swagger-UI and clone their repository into our project.

Then we remove the

dist
directory from the Swagger-UI folder and delete the remainder of the folder (it is not necessary). The
dist
folder from Swagger-UI contains a functioning example of Swagger-UI, which is all we need.

Adding Swagger to our Application

We go into our express application and begin by adding swagger,minimist, and body-parser as dependencies:

    var express = require( 'express' );
    ...
    var argv = require('minimist')(process.argv.slice(2));
    var bodyParser = require( 'body-parser' );

Then, after the app is initialized, we set swagger to a subpath to avoid route overlaps:

    var app = express();
    var subpath = express();

app.use(bodyParser());
app.use("/v1", subpath);

var swagger = require('swagger-node-express').createNew(subpath);

Next, we make sure that

/dist
is able to serve static files in express:
    app.use(express.static('dist'));

We continue by setting the info for our API:

    swagger.setApiInfo({
        title: "example API",
        description: "API to do something, manage something...",
        termsOfServiceUrl: "",
        contact: "[email protected]",
        license: "",
        licenseUrl: ""
    });

We now want to get the

/dist/index.html
file that we pulled from the Swagger-UI
dist
directory in our API.
    app.get('/', function (req, res) {
        res.sendFile(__dirname + '/dist/index.html');
    });

Finally, we configure the api-doc path, and the API domain:

        // Set api-doc path
    swagger.configureSwaggerPaths('', 'api-docs', '');

// Configure the API domain
var domain = 'localhost';
if(argv.domain !== undefined)
    domain = argv.domain;
else
    console.log('No --domain=xxx specified, taking default hostname "localhost".')

// Configure the API port
var port = 8080;
if(argv.port !== undefined)
    port = argv.port;
else
    console.log('No --port=xxx specified, taking default port ' + port + '.')

// Set and display the application URL
var applicationUrl = 'http://' + domain + ':' + port;
console.log('snapJob API running on ' + applicationUrl);


swagger.configure(applicationUrl, '1.0.0');


// Start the web server
app.listen(port);

Configuring our index.html file

Go to

/dist/index.html
and find the
url = "http://petstore.swagger.io/v2/swagger.json";
line.

We will replace it with

url = "api-docs.json";
    if (url && url.length > 1) {
        url = decodeURIComponent(url[1]);
    } else {
        url = "http://petstore.swagger.io/v2/swagger.json";
        url = "api-docs.json";
    }

Next, we will have to create a

api-docs.json
file in our
dist
directory. This file will be our Swagger-spec.

Swagger-Spec

In our

api-docs.json
file we generate a Swagger-spec.

The link will provide you with most information but it can be overwhelming so I will provide you with the most important things to know about Swagger-spec for Swagger 2.0.

Please consult here for a sample Swagger-spec.

Https vs. Http

Depending on whether our web app is serving https or http files make sure to adjust our

schemes
component of the Swagger-spec to the appropriate transfer protocol.

Example

    "schemes": [
        "https"
    ]

Tags

tags
allow for all the methods of an API to be grouped together. The tags should be described in the top of the
.json
file.
    ...
  "basePath": "/",
  "tags" : [
    {"name": "Tag1",
    "description": "API for something"
    }
  ],
  ...

Then in each path, set a

tags
parameter with whatever tag group we want the method to be apart of.
    ...
    "/path/to/method": {
       "post": {
          "tags": ["Tag1"],
          ...

    }
}

This will put all of the methods with the

"Tag1"
tag together in the UI.

Paths

Paths are exactly as they sound. They are the API method endpoints.

The

"paths"
parameter allows for nested path definitions. This can be shown in the example.

A tricky component is setting up multiple types of requests for the same path (i.e) a

get
request and a
delete
request in the same path.

How we would do this is to nest two method definitions in the same path definition.

    "/path/to/method/{someVariable}": {
        "delete":{
            ...
        },
        "get":{
            ...
        }
      }

Responses

The

responses
parameter is for describing the types of possible responses our API method can provide.

These

responses
are typically model schema (see below).

Model Schema

A powerful part of Swagger is its model

schema
. Schema are example
.json
parameters that our API method would take in or output.

Typically schema in responses or parameters are referred to by

$ref":"#/definitions/schemaName
    ...
    "schema": {
                 "$ref": "#/definitions/response"
              }
    ...

These schemas are then defined in the

definitions
section, after
paths
.
    ...
    "definitions" : {
        "schemaName" : {

    }

}

Parameters

The

parameters
parameter defines the input that our API method takes in.

The

in
parameter defines whether the input will be in the path or in the body of the API method.

Typically single (say numerical) inputs would go in the

path
, whereas
.json
inputs would use the
body
option.

The

type
of the parameter could be a varity of options.

Troubleshooting

Tags

If we do not set a

tags
parameter for a method, then it will automatically have a
default
tag

Make sure to describe our

tags
in the top of the
.json
file, we can not describe the
tags
in each specific method.

Validation

Swagger uses a validation tool to validate all specs. This can cause issues as the default validator uses

http
rather than
https
. Thus, some times it is better to turn off the validator.

To turn off validation, go to

/dist/index.html
and put in
validatorUrl: null
    ...
    window.swaggerUi = new SwaggerUi({
        //Disabled validator, as soc-api is for local use.
        validatorUrl: null,
        url: url,
    ...

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.