Express JSON Validator Middleware
express-json-validator-middleware is an Express middleware for validating incoming HTTP requests against JSON Schemas, leveraging the Ajv validator. It supports validation of `body`, `params`, `query`, or custom request properties. The current stable version is 4.0.0. The library's release cadence is often tied to significant upgrades of its underlying Ajv dependency or changes in supported Node.js and Express versions, with major versions frequently introducing breaking changes. Key differentiators include its flexible validation targets, generation of detailed error objects from Ajv that facilitate custom error handling, and robust TypeScript support for defining schemas. The primary goal is to abstract validation logic from route handlers, leading to more maintainable and expressive application code.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'street')
cause The `express.json()` middleware was not used, so `req.body` is undefined when the route handler attempts to access its properties.fixAdd `app.use(express.json());` to your Express application before defining routes that process JSON bodies. -
TypeError: Router.use() requires a middleware function but got a Object
cause The `validate` function from `express-json-validator-middleware` was not called. Instead, a plain schema object was passed directly to the Express route.fixEnsure you are calling the `validate` function with your schema object, e.g., `validate({ body: addressSchema })`, and passing the *result* to the Express route handler. -
TypeError: Validator is not a constructor
cause Attempting to `require` the `Validator` class in a CommonJS context when the library is primarily designed for ESM, or using incorrect CommonJS destructuring.fixPrefer `import { Validator } from 'express-json-validator-middleware';` in an ESM module (recommended for Node.js 24+). If strictly using CJS, ensure correct destructuring: `const { Validator } = require('express-json-validator-middleware');`. -
ReferenceError: validate is not defined
cause The `validate` function was not correctly destructured from the `Validator` instance after instantiation.fixEnsure you use `const { validate } = new Validator({ ... });` to correctly extract the method.
Warnings
- breaking Version 4.0.0 introduces updated runtime requirements, mandating Node.js >=24.0.0 and specific Express versions (4.21.2+ or 5.2.1+). Applications running on older environments will not be compatible.
- breaking Version 3.0.0 upgraded the underlying Ajv library to v8. This update can introduce breaking changes in how JSON schemas are interpreted or validated. Consult the Ajv v8 migration guide for details.
- breaking Version 1.1.0 upgraded the underlying Ajv library to v5. Similar to subsequent major Ajv upgrades, this could necessitate changes to your JSON schemas.
- gotcha The `express-json-validator-middleware` relies on Express's body parsing middleware (e.g., `express.json()`) to populate `req.body`. Without it, body validation will fail because `req.body` will be undefined.
- gotcha As of v1.1.1, the `.validate` method is automatically bound to the `Validator` instance. Manual binding (e.g., `.bind(validator)`) is no longer necessary and should be removed.
Install
-
npm install express-json-validator-middleware -
yarn add express-json-validator-middleware -
pnpm add express-json-validator-middleware
Imports
- Validator
const Validator = require('express-json-validator-middleware').Validator;import { Validator } from 'express-json-validator-middleware'; - ValidationError
const { ValidationError } = require('express-json-validator-middleware');import { ValidationError } from 'express-json-validator-middleware'; - AllowedSchema
import type { AllowedSchema } from 'express-json-validator-middleware';
Quickstart
import express from "express";
import { Validator } from "express-json-validator-middleware";
const app = express();
// Essential: This middleware parses incoming JSON requests into req.body
app.use(express.json());
const addressSchema = {
type: "object",
required: ["street"],
properties: {
street: {
type: "string",
minLength: 3
}
},
additionalProperties: false
};
// Instantiate the validator and destructure the 'validate' function
const { validate } = new Validator({ allErrors: true });
app.post("/address", validate({ body: addressSchema }), (request, response) => {
// If validation passes, request.body is guaranteed to match addressSchema
response.status(200).json({ receivedStreet: request.body.street });
});
// Global error handler for validation errors
app.use((error, request, response, next) => {
if (error instanceof Validator.ValidationError) {
console.error("Validation Error:", error.validationErrors);
response.status(400).json({
name: error.name,
validationErrors: error.validationErrors
});
return;
}
next(error);
});
const PORT = process.env.PORT ?? 3000;
app.listen(PORT, () => {
console.log(`Server listening on port ${PORT}`);
});