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
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;
(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:
- 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 alast_name
property. This object can optionally include anage
property, and if it does, the value of that property must be an integer which is greater than or equal to 18. - 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();
}
);
(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)