DEV Community

Simon Plenderleith
Simon Plenderleith

Posted on • Updated on • Originally published at learnetto.com

Learn how to handle validation in Express

These two free lessons are from 'Express API Validation Essentials'. Get the book.


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 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:

npm install express-json-validator-middleware
Enter fullscreen mode Exit fullscreen mode

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

// 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;
Enter fullscreen mode Exit fullscreen mode

(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.
// 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();
    }
);
Enter fullscreen mode Exit fullscreen mode

(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.

Top comments (0)