express-validator is a popular middleware wrapper around the validator.js library, built specifically to fit naturally into the Express middleware pipeline. This lesson covers its core API.
How express-validator Works
express-validator exposes chainable validation functions, body(), param(), query(), that you pass as middleware directly into a route. Each chain describes what a specific field must look like, and any errors accumulate without stopping the request immediately.
After the validation chains run, you call validationResult(req) inside your route handler (or a small wrapper middleware) to check whether anything failed.
const { body, validationResult } = require('express-validator');
app.post(
'/users',
body('email').isEmail().withMessage('Invalid email'),
body('age').isInt({ min: 0 }).withMessage('Age must be a positive integer'),
(req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
res.status(201).json(req.body);
}
);
Each body() call is its own middleware in the chain; validationResult(req) collects everything they found.
Validators (isEmail, isInt, notEmpty) check the value and record an error if it fails.
Sanitizers (trim, escape, toInt) transform the value in place.
withMessage() attaches a custom error message to the preceding check.
param(), query(), and body() all share the same chainable API for different input sources.
express-validator Cheatsheet
The validators and sanitizers you will use most often.
Method
Example
Purpose
body()
body('email').isEmail()
Validate a request body field
param()
param('id').isInt()
Validate a route parameter
query()
query('page').isInt({ min: 1 })
Validate a query string field
isEmail()
body('email').isEmail()
Checks valid email format
isLength()
body('password').isLength({ min: 8 })
Checks string length
trim()
body('name').trim()
Removes surrounding whitespace
validationResult()
validationResult(req)
Collects all validation errors
Reusable Validation-Handling Middleware
Checking validationResult() manually in every route is repetitive. A small reusable middleware can centralize this check across all your validated routes.
Forgetting to call validationResult(req) after the validation chains, silently ignoring all detected errors.
Placing validation chains after the route handler instead of before it in the middleware list.
Mixing up sanitizers and validators, expecting .trim() to reject empty strings (it doesn't, pair it with .notEmpty()).
Not centralizing the validationResult() check, leading to inconsistent error handling across routes.
Key Takeaways
express-validator provides chainable middleware for validating and sanitizing request data.
body(), param(), and query() target different parts of the request.
validationResult(req) collects accumulated errors for you to check and respond to.
A small reusable middleware avoids repeating the same error-check logic in every route.
Pro Tip
Chain sanitizers before validators when order matters (e.g. .trim().notEmpty()), so validation runs against the cleaned-up value rather than raw, whitespace-padded input.
You now know how to use express-validator. Next, learn an alternative schema-based approach with Joi Validation.