Validação de dados em Node.js: Joi, Yup e Zod — escolhendo a ferramenta certa
No desenvolvimento web moderno com Node.js, a validação de dados não é apenas uma boa prática, mas uma necessidade. Sem ela, seu servidor corre o risco de receber dados incorretos, maliciosos ou simplesmente inesperados do cliente. Isso pode levar a erros na lógica da aplicação, vulnerabilidades (SQL injection, XSS) e operação instável. Neste artigo, analisaremos as três bibliotecas mais populares para validação de dados no ambiente Node.js: Joi, Yup e Zod. Você conhecerá suas características, vantagens e aprenderá a aplicá-las na prática.
Por que a validação no servidor é necessária?
Muitos desenvolvedores confiam apenas na validação do frontend (por exemplo, usando atributos HTML5). Isso é um erro. A validação do cliente é fácil de contornar (desabilitando o JavaScript ou enviando uma solicitação via Postman/curl). A validação do servidor é a última linha de defesa. Ela garante que apenas dados que atendam a requisitos rigorosos entrem na sua lógica de negócios e banco de dados: tipo correto, comprimento, formato (email, URL), obrigatoriedade de campos, etc.
1. Joi — o veterano testado
Joi (frequentemente usado com o framework Hapi.js, mas funciona muito bem com Express/Koa) é uma das bibliotecas mais poderosas e flexíveis. Ela fornece uma API rica para descrever esquemas e mensagens de erro.
Instalação:
npm install joiExemplo de uso do Joi para validação de registro de usuário:
const Joi = require('joi');
const schema = Joi.object({ username: Joi.string() .alphanum() .min(3) .max(30) .required() .messages({ 'string.min': 'O nome de usuário deve ter no mínimo {#limit} caracteres', 'string.max': 'O nome de usuário deve ter no máximo {#limit} caracteres' }), password: Joi.string() .pattern(new RegExp('^[a-zA-Z0-9]{3,30}$')) .required(), email: Joi.string() .email({ minDomainSegments: 2, tlds: { allow: ['com', 'net', 'ru'] } }) .required(), birth_year: Joi.number() .integer() .min(1900) .max(2023)});
const validateUser = (data) => { const { error, value } = schema.validate(data, { abortEarly: false }); if (error) { // Retorna todos os erros return { valid: false, errors: error.details.map(d => d.message) }; } return { valid: true, data: value };};
// Exemplo de chamadaconst result = validateUser({ username: 'jo', password: '123', email: 'test@test', birth_year: 1800});console.log(result.errors);// Saída: ['O nome de usuário deve ter no mínimo 3 caracteres', '"password" length must be at least 3 characters long', '"email" must be a valid email', '"birth_year" must be less than or equal to 2023']Vantagens do Joi:
- Grande quantidade de validadores embutidos (email, URL, UUID, cartão de crédito, telefone, etc.).
- Suporte a validação condicional (when, switch).
- Ótimas mensagens de erro com possibilidade de tradução e personalização.
- Documentação detalhada.
Desvantagens:
- Tamanho da biblioteca (cerca de 60 KB compactado).
- API pode parecer pesada para esquemas simples.
- Integração complexa com TypeScript (requer tipos adicionais).
2. Yup — simplicidade e composição
Yup foi originalmente criado para validação de formulários em React (em conjunto com Formik), mas funciona muito bem no servidor também. Sua principal vantagem é a sintaxe concisa e legível, que lembra esquemas do mongoose.
Instalação:
npm install yupExemplo de validação de array de objetos com Yup:
const yup = require('yup');
cons Também na biblioteca
Superstruct para TypeScript: guia completo com exemplos
Biblioteca Padrão Java: visão geral completa para iniciantes e profissionais
Frameworks CLI para Go (Golang): uma visão geral completa das ferramentas para criar aplicações de console
ORM para Rust: comparação entre Diesel, SeaORM, SQLx e exemplos de código