OpenAPI Specification with NodeJS

Hello everyone, in this blog post we will go through the OpenAPI Specification and how to implement this in your NodeJS application.

First of all, there is great documentation on OpenAPI Specification on its official site, Do check it out.

You can use swagger-ui library to generate user interface to view those APIs.

So now that’s clear, let’s get started with this blog.

In this blog I will walk you through the process of implemntaing OpenAPI Specification in your web service/REST services.

Following are the appraoch to document your API

  1. Manually Write the OpenAPI Specification document(YAML/JSON)
  2. Integrate OpenAPI Specification with JSDoc

Write the OpenAPI Specification document(YAML/JSON)

This is very simple, here you will write your entire OpenAPI specification manually either in json or yaml. This is okay if you have very simple webservices with 1-5 API endpoints that you want to document and they are stable. because if your API are not stable then you will have to modify this document multiple times which will become error prone.

This would be suitable where you are creating background service, which would only have 1-2 API endpoint to support heavy processing.

Once you have created this document you can use swagger-ui NodeJS library to serve to your client.

Integrate OpenAPI Specification with JSDoc

If your application is very complex and large, then you should always go ahead with this.

swagger jsdoc will help you to create the OAS from your JSDoc comments added in javscript files.

Here also you have two options.

  • All OAS in JSDoc
  • Split API Specification & Shared Components

All OAS in JSDoc

If you have very simple API structure, then you can go ahead with this approach. where you will define entire path component in JSDoc.

Below JSDoc defines the API endpoint /healthcheck with some description and what response you could expect.

/**
   * @openapi
   * /healthcheck:
   *   get:
   *     tags: 
   *      - healthcheck
   *     description: Welcome to nodejs-microservices!
   *     responses:
   *       200:
   *         description: Returns a health from server.
   *       500:
   *         description: Server not responding.
   */

Above API endpint is very simple hence this is okay to define everything in JSDoc itself, now assume if you had some input parameters(path, query, cookie, header etc), request body and response body with examples. Then it would become very dificult to manage it in same JSDoc, because your JSDoc will take up too much space in your codebase and becomes very dificult to navigate and scroll through. This Problem can be solved with below solution

Split API Specification & Shared Components

This is what you should aim for if you have complex API, where lots of request/response are shared between multiple API.

In this approach, you define all of the shared component in different file/folder and reuse these shared components with $ref in your router.

/**
   * @openapi
   * /login:
   *   post:
   *     tags: 
   *      - login
   *     description: Login into microservice
   *     requestBody:
   *        description: Login request Body
   *        content:
   *          application/json:
   *            schema:
   *              $ref: "#/components/schemas/LoginRequestBody"
   *            examples:
   *              loginSuccess:
   *                $ref: "#/components/examples/LoginSuccess"
   *     responses:
   *       200:
   *         description: returns successfull login user
   *         content:
   *           application/json:
   *             schema:
   *               $ref: "#/components/schemas/LoginRequestBody" 
   *             examples:
   *               loginResponse:
   *                  $ref: "#/components/examples/LoginResponse"
   */

In Above JSDoc we have defined login API Endpoint with requestBody and responses using $ref . All the $ref components can be places outside your codebase. My preference is to keep all shared components inside api-docs folder with sub-folders for each components.

In above examples, I have added examples in JSDoc itself, but if examples are common, you should add it at #/components/schemas levels itself, to Avoid typing/managing it at multiple places.

Thanks for reading…

Leave a Reply