This article is a continuation of a series about how to build a REST API in Node.js. In the first article of this series, we created a rudimentary REST API for managing a list of employees. But that API doesn't perform any validation on the requests that are received. Therefore, nothing stops the consumer from making a request with incorrect query parameters or a malformed body. So we could for example send the following request:
POST localhost:3000/employees
{
"surname": "Symonds",
"firstname": "Andrew"
}
The API would happily add the specified object to the list of employees, even though it has the wrong names for the properties ("surname" instead of "lastName" and "firstname" instead of "firstName").
The express-openapi-validator package addresses this issue by validating requests and responses based on a provided OpenAPI spec. Having our responses validated and not just the requests will be a good idea as that will ensure the API code always responds in the expected schema.
express-openapi-validator
provides a function that takes an OpenAPI specification as a parameter and returns a request handler that we can add to Express. The most straightforward way to use it would be to write our OpenAPI spec in a JSON or YAML file and read it from this file to pass into express-openapi-validator
. But this would mean that whenever we make changes to the API in future, the corresponding part of the OpenAPI spec would have to be updated in this separate file. It would be much easier to keep the OpenAPI spec up to date if it were defined along with the relevant code.
The swagger-jsdoc package enables us to do this. It looks for JSDoc comments in code (annotated with an @openapi
tag) to generate the OpenAPI specification.
Add the express-openapi-validator
and swagger-jsdoc
packages as run-time dependencies:
npm install --save express-openapi-validator swagger-jsdoc
Let's add the JSDoc comments for defining the POST /employees
operation. This involves an employee structure, which we can define as a schema object on the EmployeesController
class:
We can then reference this schema object in a comment that we add just before the POST /employees
operation:
We use swaggerJsDoc
to generate the OpenAPI specification by telling which source files to look for the JSDoc comments via the apis
property. We then register the generated OpenAPI spec by passing it into openApiValidator
. We add all of this just before the registerRoutes()
call:
We can also set a route to serve the OpenAPI spec from localhost:3000/swagger.json
as an easy way to access the generated OpenAPI spec. This can help with troubleshooting by ensuring the spec is generated as expected and allows our API consumers to access the spec easily.
The following statement needs to be added before the app.use()
call which registers the validation. If it's added after the app.use()
a request to localhost:3000/swagger.json
will be validated and consequently return a 404 response since the /swagger.json
route is not defined in our app's OpenAPI spec.
Now, if we make the POST request as above, we get the following 400-code response:
The following post will show how we can leverage the generated OpenAPI spec to add an interactive Swagger documentation page to our API.
The code for the API developed in this series of articles is available on GitHub here.
Top comments (0)