Nunca confie na entrada
Toda a entrada que chega do cliente (req.body, req.query, req.params)
é dado não confiável. Antes de usá-la é preciso:
- Validar: verificar se ela cumpre as regras (campos presentes, tipos corretos, intervalos válidos).
- Sanear: normalizar e limpar (remover espaços, passar para minúsculas um email, descartar campos extras).
function validarUsuario(dados) {
const erros = [];
if (!dados.email) erros.push("Falta o email");
if (typeof dados.idade !== "number" || dados.idade < 0) {
erros.push("A idade deve ser um número não negativo");
}
return erros;
}
Esquemas (Zod / Joi, conceitual)
Validar na mão se torna repetitivo. As bibliotecas de esquemas declaram a forma esperada dos dados uma única vez e validam contra ela:
// Conceitual (Zod):
// const Usuario = z.object({
// email: z.string().email(),
// idade: z.number().int().nonnegative(),
// });
// const resultado = Usuario.safeParse(dados);
O esquema descreve o que se espera, não como verificá-lo passo a passo. Joi oferece uma ideia equivalente com outra sintaxe.
Responder 400 com detalhes claros
Quando a validação falha, responda com 400 (Requisição inválida) e inclua o que falhou, para que o cliente possa corrigi-lo:
const erros = validarUsuario(req.body);
if (erros.length > 0) {
return res.status(400).json({ error: "Dados inválidos", detalhes: erros });
}
Devolver uma lista de erros (em vez de parar no primeiro) é mais útil: o cliente vê todos os problemas de uma vez.
Exemplos
validarUsuario devolve a lista de problemas
function validarUsuario(dados) {
const erros = [];
if (!dados.email) erros.push("Falta o email");
if (typeof dados.idade !== "number" || dados.idade < 0) {
erros.push("A idade deve ser um número não negativo");
}
return erros;
}
console.log(validarUsuario({ email: "a@b.com", idade: 30 })); // []
console.log(validarUsuario({ idade: -1 })); // 2 erros