express-validator

Validar dados na API Node.js com express-validator

Introdução

O express-validator é uma biblioteca que pode ser utilizada no Node.js com o express, para realizar a validação dos dados de entrada na API.

Em outro post, citei a importância de realizar a validação dos dados no frontend, antes dos dados chegarem até a API para evitar o processamento sem necessidade e entre outros.

Porém, é extremamente importante realizar a validação também no backend para garantir a confiabilidade do software, prevenir erros do usuário, prevenir erros em acesso direto a API e entre outros.

Há algumas diferentes formas de realizar a validação de uma API Node.js, uma delas é utilizando o express-validator.

Sobre o express-validator

É uma biblioteca que reúne um conjunto de middlewares de validação e higienização de dados.

Os middlewares no Express são funções que tem acesso ao objeto de requisição, resposta e próximo middleware, com isso você pode adicioná-lo por exemplo entre a chamada de acesso a API e o salvamento dos dados, e isso possibilita a validação antes dos dados serem persistidos em um banco.

Para este post, o express-validator utilizado foi o da versão 6.6.1 e um pré-requisito é que o Node.js esteja na versão 6.

Para realizar a instalação, utilize o comando:

npm install --save express-validator

Como o validador funciona

Para realizar a validação dos dados da API, é necessário realizar a importação de body e validationResult, o body vai servir para validar os dados de entrada e o validationResult conterá o resultado se a entrada é válida ou não.

Posterior a essa importação, é necessário colocar a validação como um middleware na request, e é possível fazer isso utilizando um array antes do request e response, dessa forma:

app.post('/user', [
  //validação dos dados
  body('username').isEmail(),
  body('password').isLength({ min: 5 })
], (req, res) => {
  // caso encontre erros, ficará nessa variável errors
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }
  
  //se os dados forem válidos, o sistema executará aqui
});

Ao utilizar o Insomnia para fazer uma request para a rota /user, sem os dados corretos, esse será o retorno:

express-validator 1
express-validator 1

Para fazer essa request é necessário ter uma API básica em Node.js rodando. Caso queira tem um outro artigo sobre isso neste link. Esse teste também poderia ser realizado com o Postman.

Personalizar mensagem de erro

Caso queira, é possível personalizar a mensagem de erro exibida no retorno de sua API, e isso pode ser muito útil, pois a biblioteca mostra o erro em inglês, e você pode realizar essa tradução para ficar mais fácil o entendimento.

É possível fazê-lo utilizando o withMessage, passando este na frente da validação, dessa forma:

app.post('/user', [
    //validação dos dados
    body('name').notEmpty().withMessage("O campo nome é obrigatório")
], (req, res) => {
    // caso encontre erros, ficará nessa variável errors
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
    }

    //se os dados forem válidos, o sistema executará aqui
});

Com isso, a resposta do erro será essa:

Validação personalizada

Em determinados momentos, pode ser necessário criar uma forma de validação, visto que as existentes pode não suprir todas as necessidades de todos os casos.

Para isso, o express-validator aceita que seja criado um validador personalizado para cada campo.

Um exemplo útil, é caso queira validar se um e-mail já está cadastrado no banco de dados, precisa construir um validador para isso, pois é uma regra de negócio que precisa ser implementada.

Nesta regra, a API receberá um e-mail válido enviado pelo cliente e é necessário realizar a busca no banco para checar se esse e-mail existe e caso seja encontrado, o erro personalizado é retornado:

app.post('/user', body('email').custom(value => {
  return User.findUserByEmail(value).then(user => {
    if (user) {
      return Promise.reject('E-mail já cadastrado');
    }
  });
}), (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
    }
});

Exemplo prático

Para o exemplo prático, será utilizado uma API de cadastro de usuário, onde no cadastro precisará ter um e-mail válido, um nome que seja maior que 3 caracteres, idade e senha maior que 8 caracteres.

app.post('/register-user',
    [
        body('email').isEmail().withMessage("O e-mail precisa ser válido"),
        body('email').custom(value => {
            if (!value) {
                return Promise.reject('E-mail é obrigatório');
            }
            if (value == "teste@teste.com") {
                return Promise.reject('E-mail já cadastrado');
            }
            return true
        }),
        body('name').isLength({ min: 3 }).withMessage("Campo precisa ter pelo menos 3 caracteres"),
        body('password').isLength({ min: 8 }).withMessage("Campo senha precisa ter pelo menos 8 caracteres"),
        body('age').isNumeric().withMessage("Idade precisa ser um número")
    ], (req, res) => {
        const errors = validationResult(req);
        if (!errors.isEmpty()) {
            return res.status(400).json({ errors: errors.array() });
        }
        res.send({ message: 'Tudo válido' })
    });

Vale ressaltar alguns pontos desse exemplo.

Primeiramente, é possível observar que há mais de uma validação para o campo e-mail, e isso é comum e pode ser feito com qualquer campo, no caso há uma validação padrão de e-mail e também tem a validação personalizada.

No caso da validação personalizada para verificar se o e-mail já existe, deixei fixo o e-mail “teste@teste.com” somente para exemplificar, poderia ser implementado um validador igual acima no exemplo de validadores customizados.

Também tem as validações de nome e senha que precisam ter um número mínimo de caracteres, e a última validação é que a idade precisa ser um número, caso contrário irá retornar erro.

Caso tudo esteja válido irá retornar a mensagem “Tudo válido”, aqui nessa etapa onde é impresso a mensagem, que poderia ser adicionado a lógica para salvar esse registro no banco de dados e retornar ao usuário.

Vídeo completo

Caso você queira ver um vídeo completo sobre o assunto, gravei este pro canal do Youtube:

Conclusão

O express-validator é uma excelente opção para validar os dados recebidos em uma API. Realizar essa validação é importante para garantir que somente dados desejados irão entrar no banco, garantir a confiabilidade do sistema e entre diversos outros motivos, espero ter ajudado, até o próximo post 🙂

Para ver outros canais onde o posto conteúdo, meu Github e também cursos, veja os Links do Programando Soluções.

Referências

https://express-validator.github.io/docs/index.html

http://expressjs.com/en/guide/using-middleware.html

Este conteúdo te ajudou de alguma forma?

Usamos cookies para lhe proporcionar a melhor experiência possível no nosso site. Ao continuar a usar este site, você concorda com o uso de cookies.
Ok
Privacy Policy