Script Valley
Node.js: The Complete Runtime
Express.js: Building REST APIsLesson 4.3

Input validation in Express APIs with Zod or Joi

validation middleware pattern, Zod schema, Joi schema, validating req.body, req.params, req.query, returning 400 errors, schema reuse

Never Trust User Input

Validate every incoming request before touching business logic. Zod is the modern choice — it is TypeScript-first and composable.

npm install zod
const { z } = require('zod');

const CreateUserSchema = z.object({
  name: z.string().min(2).max(50),
  email: z.string().email(),
  age: z.number().int().min(0).max(120).optional()
});

function validate(schema) {
  return (req, res, next) => {
    const result = schema.safeParse(req.body);
    if (!result.success) {
      return res.status(400).json({
        error: 'Validation failed',
        issues: result.error.flatten().fieldErrors
      });
    }
    req.body = result.data;
    next();
  };
}

app.post('/users', validate(CreateUserSchema), (req, res) => {
  res.status(201).json(req.body);
});

Validating Route Params

const IdSchema = z.object({ id: z.coerce.number().int().positive() });

app.get('/users/:id', validate(IdSchema, 'params'), (req, res) => {
  // req.params.id is a number, not a string
});

Up next

Structured error handling in Express APIs

Sign in to track progress