5 min read
Add API documentation with Swagger to an express Node.js project

Short background story:

I was in the process of setting up a small side project and quickly built a backend using Node.js and the Express framework. Once I defined the initial endpoints, I started testing API requests using Postman. It occurred to me that at work, in our Spring Boot project, we use Swagger API documentation that is automatically generated and allows you to directly test API requests through its UI.

I managed to implement the same functionality for my Express backend project, and here’s a brief explanation of what I did. This is a quick view on my end result.

I got an overview of all endpoints of my application:

And i have the possibility, to test specific endpoints easily:

At first I had only found a variant in which you generate the Swagger output by manually written comments inside the code. But in the end I found out that there is also an automatically generated variant for this.

I assume that all requirements are present (npm, node,…) and that an express Project already exists. After some searches, I quickly found out which packages I needed. I installed them using npm:

npm install swagger-autogen —save npm install swagger-ui-express —save I created a swagger.js file in my root folder of the project. This is the basic file to configure then swaggerAutogen

Command. Swagger autogen will create a json file with information about the projects API endpoints. The information in

this file will be displayed via swagger-ui later on.

This is the content of my swagger.js file.

const swaggerAutogen = require('swagger-autogen')

const outputFile = './swagger_output.json'
const endpointsFiles = ['./app/index.js']

const doc = {
    info: {
        version: "1.0.0",
        title: "FoodMood Backend API",
        description: "Documentation automatically generated by the <b>swagger-autogen</b> module."
    },
    host: "localhost:3000",
    basePath: "/"
}

swaggerAutogen(outputFile, endpointsFiles, doc).then(r => console.log(r))

const outputFile = './swagger_output.json' Specifies the file path where the generated Swagger documentation will be saved

const endpointsFiles = ['./app/index.js'] An array specifying the file paths of the API endpoints to be documented. In this case, it’s assumed that the endpoints are defined in the ./app/index.js file. Also endpoint definitions that start here and proceed along other files (splitting by route, controller) are detected in this way.

const doc = { ... } Defines an object that can be used to add additional specifications to the swagger documentation.

swaggerAutogen(outputFile, endpointsFiles, doc) Invokes the swaggerAutogen function, passing the output file path, endpoints files, and the documentation object. This function generates the Swagger documentation based on the provided files and configuration. Processing the Promise results is not necessary, I just did it to see if everything works.

I created a command in the “scripts” section of my package.json to remember the command to execute the swagger auto generation. Here, you also see both of the installed swagger packages.

{
  "swagger": "2.0",
  "info": {
    "version": "1.0.0",
    "title": "FoodMood Backend API",
    "description": "Documentation automatically generated by the <b>swagger-autogen</b> module."
  },
  "host": "localhost:3000",
  "basePath": "/",
  "schemes": [
    "http"
  ],
  "paths": {
    "/api/users/": {
      "get": {
        "tags": [
          "User"
        ],
        "description": "",
        "responses": {
          "200": {
            "description": "OK"
          },
          "500": {
            "description": "Internal Server Error"
          }
        }
      },
      ...

In my case, I just added swagger UI to my main application. I don’t want to have a separate script to start the swagger

UI, it’s fine for me when it’s just up when my application is running. Later on, I could use a flag, to check if I’m in development or production mode and disable swagger UI based on this flag.

To add swagger UI to my application, i only had to add one line to my server.js / index.js file.

const app = express()

const swaggerUi = require('swagger-ui-express');
const swaggerFile = require('../swagger_output.json')

//... Route Definitions

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

By using app.use('/api/docs', swaggerUi.serve, swaggerUi.setup(swaggerFile)), the Swagger UI is mounted as a middleware at the /api/docs endpoint of the Express application. When accessing /api/docs in a browser, it will display the interactive Swagger documentation interface generated from the Swagger specification file. Make sure that ’../swagger_output.json’ is the correct path to your Swagger specification file. Which is the file that has been auto generated by the previous command.

When I start my application using my npm script command npm run dev, I can access it on localhost:3000. The swagger UI will be accessible on localhost:3000/api/docs as I defined it in my applications code.

You should be able to see a documentation of you API as you can see on the screenshots at the top of this article.

After finishing this, I only did add one more thing. I used tags to group my endpoints in swagger UI. Therefore, I used the possibility, to add sagger tags via comments. I just put them in the first line of the HTTP request handling functions in my code. In my case I did split up my code into the route definition itself, and controllers handling the requests. Here is a code snippet of how I added the comment to add a swagger tag into this function:

function getUsers(request, response) {
    // #swagger.tags = ['User']  
    userService.getUsers().then((result) => {
        response.status(200).json(result);
    }).catch(_ => {
        response.status(500).send('Could not get Users');
    });
};

Resulting in collapsable sections in swagger UI:

This is how I solved it for my project. Hope I could help someone by jotting this down while implementing it.