SyntaxStudy
Sign Up
Express.js Input Validation with express-validator
Express.js Beginner 1 min read

Input Validation with express-validator

Accepting unvalidated input is the root cause of most injection vulnerabilities. The `express-validator` package wraps the `validator.js` library into Express-compatible middleware using a chainable API: `body('email').isEmail().normalizeEmail()`. Validation chains are registered as route middleware arrays, and results are collected with `validationResult(req)`. Validation errors should return HTTP 422 Unprocessable Entity with a structured body listing each field and its error message. This allows API clients and front-end forms to surface field-level errors to users without parsing generic error strings. Sanitisers — `trim()`, `escape()`, `toInt()`, `toDate()` — clean values in place before your handler runs. Running them before validation catches whitespace-padding attacks and ensures type coercion is consistent. Complex cross-field validation is handled with `.custom()` validators that can call async database checks.
Example
// npm install express-validator
const express           = require('express');
const { body, param, validationResult } = require('express-validator');
const router            = express.Router();

// Reusable validation result handler
function validate(req, res, next) {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
        return res.status(422).json({ errors: errors.array() });
    }
    next();
}

// Create user – validation chain
const createUserRules = [
    body('name').trim().notEmpty().withMessage('name is required'),
    body('email').isEmail().normalizeEmail(),
    body('age').optional().isInt({ min: 0, max: 120 }).toInt(),
    body('password')
        .isLength({ min: 8 }).withMessage('password must be ≥ 8 chars')
        .matches(/[A-Z]/).withMessage('must contain an uppercase letter'),
];

router.post('/users', createUserRules, validate, (req, res) => {
    // By here, req.body values are sanitised and valid
    const { name, email, age, password } = req.body;
    res.status(201).json({ name, email, age });
});

// Param validation
router.get('/users/:id',
    param('id').isInt({ min: 1 }).toInt(),
    validate,
    (req, res) => {
        res.json({ id: req.params.id });
    }
);

module.exports = router;