Inicio > Cursos > Node.js y Express > Validación con Zod
Node.js y ExpressExpress.jsLección 10 de 20

Validación con Zod

Zod es una librería de validación que te permite definir exactamente qué forma deben tener tus datos. En lugar de escribir if (!body.email || !body.email.includes("@")) con decenas de condiciones manuales, defines un schema z.object({ email: z.string().email(), edad: z.number().min(18) }) y Zod valida todo automáticamente con mensajes de error claros.

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

// Definir schema de validación
const usuarioSchema = z.object({
  nombre: z.string()
    .min(2, 'Nombre debe tener al menos 2 caracteres')
    .max(100, 'Nombre muy largo'),
  email: z.string().email('Email inválido'),
  password: z.string()
    .min(8, 'Mínimo 8 caracteres')
    .regex(/[A-Z]/, 'Debe tener al menos una mayúscula')
    .regex(/[0-9]/, 'Debe tener al menos un número'),
  edad: z.number().int().min(18).max(120).optional(),
  rol: z.enum(['admin', 'usuario', 'moderador']).default('usuario'),
});

// Schema para actualización parcial (todos los campos opcionales)
const actualizarUsuarioSchema = usuarioSchema.partial().omit({ password: true });

// Middleware de validación genérico (reutilizable)
const validar = (schema) => (req, res, next) => {
  const resultado = schema.safeParse(req.body);

  if (!resultado.success) {
    // Formatear errores de Zod en algo legible
    const errores = resultado.error.issues.map(issue => ({
      campo: issue.path.join('.'),
      mensaje: issue.message,
    }));
    return res.status(400).json({ error: 'Datos inválidos', errores });
  }

  // Datos validados y parseados disponibles en req.validatedBody
  req.validatedBody = resultado.data;
  next();
};

// Query params con schema
const paginacionSchema = z.object({
  page: z.coerce.number().int().positive().default(1),
  limit: z.coerce.number().int().min(1).max(100).default(20),
  q: z.string().optional(),
});

// Uso en rutas
app.post('/usuarios', validar(usuarioSchema), async (req, res) => {
  const datosValidados = req.validatedBody; // ya está limpio y tipado
  const usuario = await usuariosService.crear(datosValidados);
  res.status(201).json(usuario);
});

app.get('/usuarios', async (req, res) => {
  const { page, limit, q } = paginacionSchema.parse(req.query);
  const usuarios = await usuariosService.listar({ page, limit, q });
  res.json(usuarios);
});
ConsejoUsa schema.safeParse() en lugar de schema.parse() en middlewares. safeParse() devuelve { success, data } o { success: false, error } sin lanzar excepciones. parse() lanza ZodError que puede romper tu app si no la capturas.
← Autenticación con JWTPrisma ORM →

Practica esta lección

Resuelve los ejercicios del curso de Node.js y Express en la app, gratis y con corrección automática.

Empezar a practicar