The Simplest Way to Add Swagger to a Node.js Project

From Logic Wiki
Jump to: navigation, search


Install OpenAPI to an Existing Project

Install library

Run npm i swagger-ui-express to install Swagger UI Express.

Add Swagger documents

There are two choices from here for the format:

  • JSON
  • TypeScript extension

use the Typescript extension to create a good reusable and readable swagger document.

export const swaggerDocument = {
    openapi: '3.0.1',
    info: {
        version: '1.0.0',
        title: 'APIs Document',
        description: 'your description here',
        termsOfService: '',
        contact: {
            name: 'Tran Son hoang',
            email: 'son.hoang01@gmail.com',
            url: 'https://hoangtran.co'
        },
        license: {
            name: 'Apache 2.0',
            url: 'https://www.apache.org/licenses/LICENSE-2.0.html'
        }
    }
}

Inject the document into the project

We just need to import the library swagger-ui-express and your swagger.ts file to your server.

Here I add it into the project using the URL /api-docs

Swagger.png

Simple Guide to Writing Good Documentation

To add more information for servers, we have DEV, SIT, UAT, and maybe Pre-Production environment for our API service.

export const swaggerDocument = {
    ...
    servers: [
        {
            url: 'http://localhost:3000/api/v1',
            description: 'Local server'
        },
        {
            url: 'https://app-dev.herokuapp.com/api/v1',
            description: 'DEV Env'
        },
        {
            url: 'https://app-uat.herokuapp.com/api/v1',
            description: 'UAT Env'
        }
    ],
    ...
}

if you want to have dynamic ports, environment name, and a base path? We can apply variables for this.

export const swaggerDocument = {
    ...
    servers: [
        {
            "url": "https://{env}.gigantic-server.com:{port}/{basePath}",
            "description": "The production API server",
            "variables": {
                "env": {
                    "default": "app-dev",
                    "description": "DEV Environment"
                },
                "port": {
                    "enum": [
                        "8443",
                        "3000",
                        "443"
                    ],
                    "default": "8443"
                },
                "basePath": {
                    "default": "v1"
                }
            }
        }
    ],
    ...
}

How can you add authorization to Swagger?

export const swaggerDocument = {
    ...
    components: {
        schemas: {},
        securitySchemes: {
            bearerAuth: {
                type: 'http',
                scheme: 'bearer',
                bearerFormat: 'JWT'
            }
        }
    }
    ...
}

The sample code above is for adding JWT to a request header to authorize the user's permissions. We also have other authentication types like:

Basic Authentication

{
  "type": "http",
  "scheme": "basic"
}

API Key

{
  "type": "apiKey",
  "name": "api_key",
  "in": "header"
}

Implicit OAuth2

{
  "type": "oauth2",
  "flows": {
    "implicit": {
      "authorizationUrl": "https://example.com/api/oauth/dialog",
      "scopes": {
        "write:pets": "modify pets in your account",
        "read:pets": "read your pets"
      }
    }
  }
}

Split out the swagger into smaller files

Create one file called pets.swagger.ts inside src/openAPI

export const getPets = {
    tags: ['Pets'],
    description: "Returns all pets from the system that the user has access to",
    operationId: 'getPets',
    security: [
        {
            bearerAuth: []
        }
    ],
    responses: {
        "200": {          
            description: "A list of pets.",
            "content": {
                "application/json": {
                    schema: {
                        type: "array",
                        items: {
                            pet_name: {
                                type: 'string',
                                description: 'Pet Name'
                            },
                            pet_age: {
                                type: 'string',
                                description: 'Pet Age'
                            }
                        }
                    }
                }
            }
        }
    }
} 

Import getPets to swagger.ts

import { getPets } from './openAPIs/pets.swagger';

export const swaggerDocument = {
    ...
    tags: [
        {
            name: 'Pets'
        }
    ],
    paths: {
        "/pets": {
            "get": getPets
        }
    }
    ...
}

By using Typescript, we can split the document into many small files based on business logic. This makes our swagger document is more readable and maintainable.