Learn how to handle validation in Express
Tags: node, express, validation
Published: 2021-04-22 14:56:11


> **These two free lessons are from 'Express API Validation Essentials'. [Get the book](https://expressapivalidation.com/).**

----

## Integrating Ajv into your Express application

You can use the Ajv library directly, however for an Express based API it's nice to be able to use middleware to validate request data which has been sent to an endpoint before that endpoint's route handler is run. This allows you to prevent things like accidentally storing invalid data in your database. It also means that you can handle validation errors and send a useful error response back to the client. The [express-json-validator-middleware](https://github.com/vacekj/express-json-validator-middleware) package can help you with all of this.

The `express-json-validator-middleware` package uses Ajv and allows you to pass configuration options to it. This is great as it means you have full control to configure Ajv as if you were using it directly.

Before we integrate this middleware into our application, let's get it installed:

```bash
npm install express-json-validator-middleware
```

Once you have it installed you need to require it in your application and configure it:

```javascript
// src/middleware/json-validator.js

import { Validator } from "express-json-validator-middleware";

/**
 * Create a new instance of the `express-json-validator-middleware`
 * `Validator` class and pass in Ajv options if needed.
 *
 * @see https://github.com/ajv-validator/ajv/blob/master/docs/api.md#options
 */
const validator = new Validator();

export default validator.validate;
```

_(Example 2.6)_

## Using a JSON schema to validate a response body

In this next piece of code we're going to do two things:

1. Define a JSON schema to describe the data we expect to receive when a client calls our API endpoint to create a new user. We want the data to be an object which always has a `first_name` and a `last_name` property. This object can optionally include an `age` property, and if it does, the value of that property must be an integer which is greater than or equal to 18.
2. Use the user schema which we've defined to validate requests to our `POST /user` API endpoint.

```javascript
// src/schemas/user.schema.js

const userSchema = {
	type: "object",
	required: ["first_name", "last_name", "age"],
	properties: {
		first_name: {
			type: "string",
			minLength: 1,
		},
		last_name: {
			type: "string",
			minLength: 1,
		},
		age: {
			type: "number",
		},
	},
};

export default userSchema;

// src/server.js

import validate from "./middleware/json-validator.js";

import userSchema from "./schemas/user.schema.js";

app.post(
	"/user",
	validate({ body: userSchema }),
	function createUserRouteHandler(request, response, next) {
		/**
		 * Normally you'd save the data you've received to a database,
		 * but for this example we'll just send it back in the response.
		 */
		response.json(request.body);

		next();
	}
);
```

_(Example 2.7)_

In the route definition above we're calling the `validate()` method from our `Validator` instance. We pass it an object telling it which request properties we want to validate, and what JSON schema we want to validate the value of each property against. It is configured to validate the `body` property of any requests to the `POST /user` endpoint against our `userSchema` JSON schema.

The `validate()` method compiles the JSON schema with Ajv, and then returns a middleware function which will be run every time a request is made to this endpoint. This middleware function will take care of running the validation which we've configured.

If the request `body` validates against our `userSchema`, the middleware function will call the `next()` Express function which was passed to it and our route handler function will be run. If Ajv returns a validation error, the middleware  will call the `next()` Express function with an error object which has a `validationErrors` property containing an array of validation errors. Our route handler function will _not_ be run. We'll look at where that error object gets passed to and how we can handle it in the next part of this book.

---

> **If you've enjoyed these free lessons from 'Express API Validation Essentials', [get the book](https://expressapivalidation.com/).**