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
- Manually Write the OpenAPI Specification document(YAML/JSON)
- 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…