How To Use Swagger/OpenAPI In A Node Express Application

Separating Swagger Files Into Individual Models

In this tutorial, we are going to learn how to integrate openAPI into an existing Express application. What's more, you will learn how to break your openAPI files into small chunks, how cool is that!

Why would you want to Use OpenAPI.

The OpenAPI Specification (OAS) defines a standard, language-agnostic interface to RESTful APIs which allows both humans and computers to discover and understand the capabilities of the service without access to source code, documentation, or through network traffic inspection. Source (swagger.io). In plain English, it creates a playground where one can interact with your APIs without them having access to your code.

Getting Started

To get openAPI working with our project there are a few packages that we would have to install.

npm install swagger-jsdoc swagger-ui-express

In side our entry point file, usually server.js or app.js, we will import the new packages we just installed as such

const swaggerJSDoc = require('swagger-jsdoc');
const swaggerUi = require('swagger-ui-express');

Next, we have to add an openAPI definition. This will provide some meta data about our openAPI. We will do this in the same file we imported the packages

const swaggerDefinition = {
  openapi: "3.0.0",
  info: {
    title: "Your Title",
    version: "0.1.0",
    description: "Some description about your APIs",
    contact: {
      name: "Your name",
    },
  },
  servers: [
    {
      url: "http://localhost:8080",
    },
  ],
};

We are using openAPI version 3. Pay attention to the url in the servers array. If you are running on a different port then you might want to replace the 8080 with the port you are using. The rest of the information are intuitive and you can modify them as you deem fit. Next we are going to define the options for our swaggerJSDoc.

const options = {
  swaggerDefinition,
  apis: ['./docs/**/*.yaml'],
};

Pay attention to the apis property, this is what makes it possible for us to break our openAPI files into smaller pieces. For this tutorial, we are using yaml for our openAPI files and we have to make sure that inside the root of our application we create a folder called docs where everything related to openAPI as far as documentation is concerned will reside. We will then go ahead and and initialize swaggerJSDoc.

const swaggerSpec = swaggerJSDoc(options);

Finally we need to define a route by which we will access the API documentation

app.use('/api-docs',swaggerUi.serve, swaggerUi.setup(swaggerSpec));

I'm using app as the result of calling express like so const app = express();

At this point we have finished setting up openAPI and our entire setup looks something like this

const express = require('express');
const swaggerJSDoc = require('swagger-jsdoc');
const swaggerUi = require('swagger-ui-express');

const app = express();
const swaggerDefinition = {
  openapi: "3.0.0",
  info: {
    title: "Your Title",
    version: "0.1.0",
    description: "Some description about your APIs",
    contact: {
      name: "Your name",
    },
  },
  servers: [
    {
      url: "http://localhost:8080",
    },
  ],
};

const options = {
  swaggerDefinition,
  apis: ['./docs/**/*.yaml'],
};
const swaggerSpec = swaggerJSDoc(options);

app.use('/api-docs',swaggerUi.serve, swaggerUi.setup(swaggerSpec));

module.exports = app;

Now, all we have to do is to start adding yaml files in our docs directory with some API documentations. Because this tutorial is not meant to teach openAPI I'm not going to go into the details of the yaml files. So, inside the docs folder which we created in the root of our application, create a new file called user.yaml and paste the code below into it

paths:
  /users/:
    post:                 
      tags:               
        - User            
      summary: creates a new user
      produces:
      - application/json
      parameters:         
      - in: body          
        name: sign up     
        description: Creates a new user
        required: false   
        schema:           
          $ref: '#/definitions/User' 
      responses:          
        201:
          description: An object with user details
definitions:        
  User:
    type: object
    properties:
      user:
        type: object
        properties:
          username:
            type: string
          email:
            type: string
          password:
            type: string

Be mindful of the indentation because it's a yaml file otherwise you might experience some errors.

Finally the moment of truth, we will visit the route localhost:8080/api-docs and we should see the swaggerUi and the User model we added to our docs.

Clean Up

How about we do some refactoring so that our entry point file doesn't get concerned will so much openAPI definitions. If this feels like a great idea to you it feels same to me too. Let's create a new file in the root of our application called swagger-spec.js. Inside this file we are going to move most of our openAPI definitions there like so

const swaggerJSDoc = require('swagger-jsdoc');

const swaggerDefinition = {
  openapi: "3.0.0",
  info: {
    title: "Your Title",
    version: "0.1.0",
    description: "Some description about your APIs",
    contact: {
      name: "Your name",
    },
  },
  servers: [
    {
      url: "http://localhost:8080",
    },
  ],
};
const options = {
  swaggerDefinition,
  apis: ['./docs/**/*.yaml'],
};
const swaggerSpec = swaggerJSDoc(options);

module.exports = swaggerSpec;

Now inside our app.js all we have to do is to import this swagger-spec.js file. I think our code looks a lot better now. Below is how our refactored code will look like

const express = require('express');
const swaggerUi = require('swagger-ui-express');
const swaggerSpec = require('./swagger-spec');

const app = express();

app.use('/api-docs',swaggerUi.serve, swaggerUi.setup(swaggerSpec));

module.exports = app;

Pro Tip

If you are using something like nodemon to automatically reload your server when new changes are saved, note that it will not reload when you add new content to your yaml files. You will either have to restart the server manually or go into a .js file and do a save.

Connect with me on Linkend and Twitter . Happy Learning!