NodeJs Swagger documentation

With`@swagger` comments and Express server

Allen Kim
Digital-Heart

--

On this article, I am going to create a Swagger documentation of an Express NodeJs API.

This example Express API has the following urls and it will be grouped as users.

  • GET /users
  • POST /users
  • GET /users/:id
  • PUT /users/:id
  • DELETE /users/:id

First, create a NodeJs Express project and install dependencies.

$ npm init - y
$ npm install express body-parser swagger-jsdoc swagger-ui-express

For Swagger documentation, you need two files.

  1. Swagger definition file, ./swagger.js
  2. API entry point, ./index.js

Let me create these two files.

Swagger definition file, ./swagger.js

./swagger.js

/**
* @swagger
* components:
* schemas:
* User:
* type: object
* required:
* - first
* - last
* properties:
* id:
* type: integer
* description: The Auto-generated id of a user
* first:
* type: string
* description: first name
* last:
* type: string
* descripton: last name
* example:
* id: 1
* first: John
* last: Doe
*
* @swagger
* tags:
* name: Users
* description: list of users
*/
const swaggerJsDoc = require('swagger-jsdoc');
const swaggerSpecs = swaggerJsDoc({
definition: {
openapi: "3.0.0",
info: {
title: "Users API",
version: "1.0.0",
description: "A simple Express Library API"
},
servers: [
{
url: "http://localhost:3000",
description: "My API Documentation",
},
],
},
apis: ["./*.js"] // process @swagger in ./swagger.js and ./users.js
});
module.exports = swaggerSpecs;

This file has swagger definition for swagger-jsdoc, and Swagger common documentation; components and tags.

User component:

This tells how User is composed of, first name, last name, and what users mean.

To know more about necessary Swagger definitions, please visit Basic Structure (swagger.io).

Users tag:

Swagger UI uses Users tag to group multiple operations.

If you are interested in more about Swagger components, refer these links;

API entry point, ./index.js

Application starting point.

./index.js

const express = require('express');
const swaggerUI = require('swagger-ui-express');

const usersRouter = require('./users');
const swaggerSpec = require('./swagger');

const app = express();
app.use("/users", usersRouter);
app.use("/api-docs", swaggerUI.serve, swaggerUI.setup(swaggerSpec));

app.listen(3000, () => console.log(`Server runs on port 3000, http://localhost:3000/users`));

As you see in index.js, it requires ./users.js file , which is Express routes for users API.

./users.js

const express = require('express');
const bodyParser = require('body-parser');
const users = [
{ id: 1, first: "Allen", last: "Kim" },
{ id: 2, first: "Hello", last: "World" },
{ id: 3, first: "John", last: "Doe" }
];

const router = express.Router();
router.use(bodyParser.json()); // to use body object in requests

/**
* @swagger
* /users:
* get:
* summary: Returns all users
* tags: [Users]
* responses:
* 200:
* description: the list of users
* content:
* application/json:
* schema:
* type: array
* items:
* $ref: '#/components/schemas/User'
*/
router.get("/", (req, res) => {
res.send(users);
});

/**
* @swagger
* /users/{id}:
* get:
* summary: gets user info. by id
* tags: [Users]
* parameters:
* - in : path
* name: id
* description: id of user
* schema:
* type: integer
* required: true
* responses:
* 200:
* description: user info.
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/User'
* 404:
* description: user is not found
*/
router.get("/:id", (req, res) => {
const user = users.find((el) => el.id === +req.params.id);
user ? res.send(user) : res.sendStatus(404);
});

/**
* @swagger
* /users:
* user:
* summary: Create a new user
* tags: [Users]
* requestBody:
* required: true
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/User'
* responses:
* 200:
* description: The user was successfully created
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/User'
* 500:
* description: Some server error
*/
router.post("/", (req, res) => {
const user = { ...req.body, id: users.length + 1 };
res.send([...users, user]);
});

/**
* @swagger
* /users/{id}:
* put:
* summary: updates a user by id
* tags: [Users]
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: user id
* requestBody:
* required: true
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/User'
* responses:
* 200:
* decsription: The user was updated
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/User'
* 500:
* description: Some errors happend.
*/
router.put("/:id", (req, res) => {
const existing = users.find((el) => el.id === +req.params.id);
const user = Object.assign(existing, {first, last} = req.body);
res.send(user);
});


/**
* @swagger
* /users/{id}:
* delete:
* summary: removes a user by id
* tags: [Users]
* parameters:
* - in: path
* name: id
* description: user id
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: The user was deleted
* 404:
* description: The post was not found
*/
router.delete("/:id", (req, res) => {
const index = users.findIndex((el) => el.id === +req.params.id);
users.splice(index, 1);
res.sendStatus(200);
});

module.exports = router;

Now, you are ready. start the Express server

$ node index.js
Server runs on port 3000, http://localhost:3000/users

Once started, check API features from browser

Your API is working. Now, open Swagger documentation.

It seems all good including running your API on the browser.

That’s it.

Hope it was simple for you. You can download working code from allenhwkim/swagger-nodejs (github.com).

Bonus: How do you get swagger.json, so that you can share it?

The above approach does not use swagger.json . However, you might be curious how swagger.json is created.

You can get your swagger.json by running the following command.

$ npx swagger-jsdoc -d swagger.js index.js

The above command requires two files. The first is swagger definition file, which is swagger.js , and the second is API spec. You can provide index.js which imports all Swagger API spec comments, @swagger .

When you run the above, you will see swagger.json is created.

$ npx swagger-jsdoc -d swagger.js index.js
Swagger specification is ready.

./swagger.json

{
"openapi": "3.0.0",
"info": {
"title": "Users API",
"version": "1.0.0",
"description": "A simple Express Library API"
},
"servers": [
{
"url": "http://localhost:3000",
"description": "My API Documentation"
}
],
"paths": {
"/users": {
"get": {
...
},
"user": {
...
}
},
"/users/{id}": {
"get": {
...
},
"put": {
...
},
"delete": {
...
}
}
},
"components": {
"schemas": {
"User": {
...
}
}
},
"tags": [
{
"name": "Users",
"description": "list of users"
}
]
}

If this is helpful, give me some claps 👏👏👏👏👏, which helps promoting this article.

Happy coding :)

Allen Kim, Oct 17th, 2023

--

--