Introdução
Ao criar uma aplicação que recebe dados externos, seja através de um formulário, API ou CLI, é fundamental validar as informações. Afinal, não se pode esperar que os usuários sempre enviem os dados no formato esperado. Por isso, deve haver uma camada de validação para evitar erros e garantir que as informações recebidas estejam corretas.
Solução Nativa
Uma das formas de validar os dados é usando a própria linguagem para criar validações personalizadas.
Você pode criar classes específicas para cada tipo de validação presente na aplicação:
class IntegerValidation {
#fieldName;
constructor(fieldName) {
this.#fieldName = fieldName;
}
validate(obj) {
const field = Number(obj[this.#fieldName]);
if (!Number.isInteger(field)) {
return new Error(`O campo ${this.#fieldName} deve ser um inteiro.`);
}
}
}
const input = { "age": 10.3 };
const ageValidation = new IntegerValidation("age");
const error = ageValidation.validate(input);
if (error) {
// Error: O campo age deve ser um inteiro.
return res.status(400).json({ error: error.message });
}
// Se chegar aqui, a validação funcionou e os dados estão corretos.
return res.status(200).json({ message: "ok" });
Essa abordagem permite que você tenha total controle sobre as validações e possa reutilizá-las facilmente. Além disso, é possível criar um objeto composto de várias validações, facilitando a manutenção ao adicionar ou remover regras conforme necessário:
class ValidationComposite {
#validations = [];
constructor(validations) {
this.#validations = validations;
}
validate(obj) {
for (const validation of this.#validations) {
const error = validation.validate(obj);
if (error) {
return error;
}
}
}
}
const validations = [
new RequiredField("name"),
new RequiredField("age"),
new RequiredField("password"),
new IntegerValidation("age"),
new NameValidation("name"),
new PasswordValidation("password")
];
const validationComposite = new ValidationComposite(validations);
const input = {
name: "Fulano",
age: 24,
password: "Senha@1234"
};
const error = validationComposite.validate(input);
if (error) {
return res.status(404).json(error);
}
return res.status(200).json({ message: "ok" });
A desvantagem dessa abordagem é que você precisaria escrever manualmente todas as classes de validação, o que pode demandar tempo.
Uso de Bibliotecas
Se criar as validações do zero for trabalhoso demais, você pode utilizar bibliotecas que já fazem esse trabalho. Algumas das principais bibliotecas de validação em JavaScript são:
A sintaxe de uso dessas bibliotecas é bastante semelhante. Veja um exemplo utilizando Joi:
const Joi = require("joi");
const schema = Joi.object({
name: Joi.string().min(3).required(),
age: Joi.number().integer().min(18).required(),
password: Joi.string().pattern(new RegExp('^[a-zA-Z0-9]{3,30}$')).required()
});
const input = {
name: "Fulano",
age: 24,
password: "Senha@1234"
};
const result = schema.validate(input);
if (result.error) {
return res.status(400).json({ error: result.error.details });
}
// Se a validação for bem-sucedida, os dados estarão em result.value
return res.status(200).json(result.value);
Conclusão
Independentemente da abordagem escolhida, o importante é garantir que sua aplicação valide adequadamente os dados recebidos, evitando problemas e melhorando a experiência do usuário final.
Top comments (0)