Documenting Routes with Swagger

In our project, Swagger is initialized in the file backend/src/index.js

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

...

const options = {
    ...
    servers: [
      {
        url: config.swaggerUrl,
        description: 'Development server',
      },
    ],
    ...    
};  

const specs = swaggerJsDoc(options);
app.use(
  '/api-docs',
  function (req, res, next) {
    swaggerUI.host = req.get('host');
    next();
  },
  swaggerUI.serve,
  swaggerUI.setup(specs),
);

The Swagger configuration is in the file backend/src/config.js

    ...

  swaggerUI: process.env.NODE_ENV === 'production' ? '' : '<http://localhost>',
  swaggerPort: process.env.NODE_ENV === 'production' ? '' : ':8080',

  ...

  config.swaggerUrl = `${config.swaggerUI}${config.swaggerPort}`;

To add an endpoint to a swagger, you must annotate @swagger with the appropriate content before the endpoint.

Below is an example of adding the /api/users endpoint to the swagger to create a new user:

/**
 *  @swagger
 *  /api/users:
 *    post:
 *      security:
 *        - bearerAuth: []
 *      tags: [Users]
 *      summary: Add new item
 *      description: Add new item
 *      requestBody:
 *        required: true
 *        content:
 *          application/json:
 *            schema:
 *              properties:
 *                data:
 *                  description: Data of the updated item
 *                  type: object
 *                  $ref: "#/components/schemas/Users"
 *      responses:
 *        200:
 *          description: The item was successfully added
 *          content:
 *            application/json:
 *              schema:
 *                $ref: "#/components/schemas/Users"
 *        401:
 *          $ref: "#/components/responses/UnauthorizedError"
 *        405:
 *          description: Invalid input data
 *        500:
 *          description: Some server error
 */

router.post(
  '/',
  wrapAsync(async (req, res) => {
    const link = new URL(req.headers.referer);
    await UsersService.create(req.body.data, req.currentUser, true, link.host);
    const payload = true;
    res.status(200).send(payload);
  }),
);

Of the key properties that need to be set in the swagger are

  • /api/users - documented endpoints
  • post - used HTTP method
  • requestBody - description of data passed to the function
  • responses - description of response codes of the function

For a more detailed study of the swagger, you can refer to the documentation https://swagger.io/docs/specification/basic-structure/

Setting Up Swagger in Your Project

In our project, Swagger is initialized in the backend/src/index.js file. Swagger provides a powerful way to document your API, making it easy for developers to understand and interact with it.

Swagger Initialization

Here’s (backend/src/index.js) how we initialize Swagger:

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

...

const options = {
    ...
    servers: [
      {
        url: config.swaggerUrl,
        description: 'Development server',
      },
    ],
    ...
};

const specs = swaggerJsDoc(options);
app.use(
  '/api-docs',
  function (req, res, next) {
    swaggerUI.host = req.get('host');
    next();
  },
  swaggerUI.serve,
  swaggerUI.setup(specs),
);
...

Swagger Configuration

The Swagger configuration is located in the backend/src/config.js file:

...

swaggerUI: process.env.NODE_ENV === 'production' ? '' : '<http://localhost>',
swaggerPort: process.env.NODE_ENV === 'production' ? '' : ':8080',

...

config.swaggerUrl = `${config.swaggerUI}${config.swaggerPort}`;

Adding an Endpoint to Swagger

To add an endpoint to Swagger, you need to annotate the endpoint with the appropriate Swagger documentation.

Below is an example of adding the /api/users endpoint for creating a new user:

/**
 *  @swagger
 *  /api/users:
 *    post:
 *      security:
 *        - bearerAuth: []
 *      tags: [Users]
 *      summary: Add new user
 *      description: Create a new user
 *      requestBody:
 *        required: true
 *        content:
 *          application/json:
 *            schema:
 *              properties:
 *                data:
 *                  description: User data
 *                  type: object
 *                  $ref: "#/components/schemas/Users"
 *      responses:
 *        200:
 *          description: User successfully created
 *          content:
 *            application/json:
 *              schema:
 *                $ref: "#/components/schemas/Users"
 *        401:
 *          $ref: "#/components/responses/UnauthorizedError"
 *        405:
 *          description: Invalid input data
 *        500:
 *          description: Server error
 */

router.post(
  '/',
  wrapAsync(async (req, res) => {
    const link = new URL(req.headers.referer);
    await UsersService.create(req.body.data, req.currentUser, true, link.host);
    const payload = true;
    res.status(200).send(payload);
  }),
);

Key Properties for Swagger Documentation

  • /api/users: The endpoint being documented.
    • post: The HTTP method used.
      • security: Specifies that the endpoint requires bearer token authentication.
      • tags: Categorizes the endpoint under "Users".
      • summary: Provide a summary.
      • description: Description of the endpoint.
      • requestBody: Indicates that the request body is required and describes its content.
      • responses: Describes the possible responses from the endpoint.

Further Reading

For more detailed information on how to use Swagger, refer to the Swagger documentation.