Nunca confíes en la entrada
Toda la entrada que llega del cliente (req.body, req.query, req.params)
es datos no fiables. Antes de usarla hay que:
- Validar: comprobar que cumple las reglas (campos presentes, tipos correctos, rangos válidos).
- Sanear: normalizar y limpiar (recortar espacios, pasar a minúsculas un email, descartar campos extra).
function validarUsuario(datos) {
const errores = [];
if (!datos.email) errores.push("Falta el email");
if (typeof datos.edad !== "number" || datos.edad < 0) {
errores.push("La edad debe ser un número no negativo");
}
return errores;
}
Esquemas (Zod / Joi, conceptual)
Validar a mano se vuelve repetitivo. Las librerías de esquemas declaran la forma esperada de los datos una sola vez y validan contra ella:
// Conceptual (Zod):
// const Usuario = z.object({
// email: z.string().email(),
// edad: z.number().int().nonnegative(),
// });
// const resultado = Usuario.safeParse(datos);
El esquema describe qué se espera, no cómo comprobarlo paso a paso. Joi ofrece una idea equivalente con otra sintaxis.
Responder 400 con detalles claros
Cuando la validación falla, responde con 400 (Petición inválida) e incluye qué falló, para que el cliente pueda corregirlo:
const errores = validarUsuario(req.body);
if (errores.length > 0) {
return res.status(400).json({ error: "Datos inválidos", detalles: errores });
}
Devolver una lista de errores (en vez de parar en el primero) es más útil: el cliente ve todos los problemas de una vez.
Ejemplos
validarUsuario devuelve la lista de problemas
function validarUsuario(datos) {
const errores = [];
if (!datos.email) errores.push("Falta el email");
if (typeof datos.edad !== "number" || datos.edad < 0) {
errores.push("La edad debe ser un número no negativo");
}
return errores;
}
console.log(validarUsuario({ email: "a@b.com", edad: 30 })); // []
console.log(validarUsuario({ edad: -1 })); // 2 errores