Adding request and response validation to your Express REST API
Tags: node, rest, express, tutorial
Published: 2021-09-01 04:51:09

This article is a continuation of a series about how to build a REST API in Node.js. In the [first article](https://dev.to/bhaeussermann/building-a-node-js-rest-api-14o7) 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](https://github.com/cdimascio/express-openapi-validator) package addresses this issue by validating requests and responses based on a provided [OpenAPI](https://swagger.io/docs/specification/about/) 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](https://github.com/Surnet/swagger-jsdoc) package enables us to do this. It looks for [JSDoc](https://jsdoc.app/) 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:

{% gist https://gist.github.com/bhaeussermann/0351195aa17c1973e7340f4153a790e2 %}

We can then reference this schema object in a comment that we add just before the `POST /employees` operation:

{% gist https://gist.github.com/bhaeussermann/bcca0c6271f6afa50b272ed25fdcbefe %}

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:

{% gist https://gist.github.com/bhaeussermann/c88ecc835551864c8d745208d92ff2db %}

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.

{% gist https://gist.github.com/bhaeussermann/df9fed7b792f21dba689d2907303859f %}

Now, if we make the POST request as above, we get the following 400-code response:

{% gist https://gist.github.com/bhaeussermann/39aa50d63b659572d584d01157f9324f %}

The [following post](https://dev.to/bhaeussermann/adding-a-swagger-ui-page-to-your-express-rest-api-3cbc) 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](https://github.com/bhaeussermann/node-js-rest-api).*