Script Valley
Express.js: APIs and Middleware
Middleware Deep DiveLesson 2.3

How to write request validation middleware in Express

validation middleware, req.body checks, 400 Bad Request, early return pattern, field presence checking, type checking, reusable validators, middleware factory functions

Request Validation Middleware

Validation middleware checks req.body before the route handler runs. If data is invalid, it responds immediately with 400 — the route handler never executes.

Simple field validation middleware

function validateUser(req, res, next) {
  const { name, email } = req.body;

  if (!name || typeof name !== 'string') {
    return res.status(400).json({ error: 'name is required and must be a string' });
  }

  if (!email || !email.includes('@')) {
    return res.status(400).json({ error: 'valid email is required' });
  }

  next();
}

// Apply only to the POST route
app.post('/users', validateUser, (req, res) => {
  const user = { id: Date.now(), ...req.body };
  res.status(201).json(user);
});

Reusable validator factory

function requireFields(...fields) {
  return (req, res, next) => {
    const missing = fields.filter(f => !req.body[f]);
    if (missing.length) {
      return res.status(400).json({ error: `Missing fields: ${missing.join(', ')}` });
    }
    next();
  };
}

app.post('/products', requireFields('name', 'price', 'stock'), handler);

The factory pattern makes validators reusable across routes. For production apps, use a library like zod or joi — but this pattern is the foundation they're built on.

Up next

How third-party middleware works — morgan, cors, helmet

Sign in to track progress