{"componentChunkName":"component---src-templates-blog-post-js","path":"/express-celebrate-joi/","result":{"data":{"markdownRemark":{"html":"<h2 id=\"Introducao\" style=\"position:relative;\">Introdução<a href=\"#Introducao\" aria-label=\"Introducao permalink\" class=\"anchor after\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a></h2>\n<p>No último <a href=\"https://programadev.com.br/express-rest-db/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">artigo</a> vimos como integrar a uma aplicação <strong>Express</strong> com o banco de dados não relacional <strong>MongoDB</strong>. Porém detectamos que estávamos expondo mais informações do que queríamos na resposta das operações, ex:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token punctuation\">{</span>\n    <span class=\"token string\">\"id\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token number\">1</span>,\n    <span class=\"token string\">\"name\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"Kelly\"</span>,\n    <span class=\"token string\">\"telephone\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"118888888\"</span>,\n    <span class=\"token string\">\"address\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"Rua dos Bobos n 1\"</span>,\n    <span class=\"token string\">\"_id\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"607d805caa972341ebd3e568\"</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>A exposição do campo <code class=\"language-text\">_id</code> não é uma boa pratica pois pode expor detalhes internos que não queremos compartilhar com o mundo externo.</p>\n<p>Além disso a API ainda não efetua nenhuma validação sobre os dados que recebe e como queremos manter a consistência dos dados que serão inseridos iremos adicionar ao projeto a biblioteca de validações <strong>Joi</strong> e o middleware <strong>Celebrate</strong> para tratamento das respostas da API.</p>\n<h2 id=\"Transformando-o-modelo\" style=\"position:relative;\">Transformando o modelo<a href=\"#Transformando-o-modelo\" aria-label=\"Transformando o modelo permalink\" class=\"anchor after\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a></h2>\n<p>No primeiro <a href=\"https://programadev.com.br/express-rest-I/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">artigo</a> criamos a classe <strong>Contact</strong> mas não chegamos a usá-la, agora iremos revê-la e começaremos a usar o modelo na aplicação.</p>\n<p>É muito importante ser definido um domínio para a sua aplicação, um domínio bem estruturado e planejado impede que aplicações que começaram simples cresçam sem controle, agregando mais responsabilidades do que deveriam lidar. Esse é um problema antigo mas com o advento dos <em>microservices</em> ficou explícito o quanto é importante haver um domínio bem estruturado.</p>\n<p>Nessa aplicação o domínio é óbvio, contatos, porém nem sempre isso é tão claro e vale a pena investir um bom tempo separando os domínios de uma aplicação e como eles se relacionam e trocam informações uns com os outros.</p>\n<p>Olhando para o arquivo na pasta <strong>model</strong> temos o seguinte:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> Contact <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n\n    id<span class=\"token operator\">:</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span>\n    name<span class=\"token operator\">:</span> <span class=\"token string\">\"\"</span><span class=\"token punctuation\">,</span>\n    telephone<span class=\"token operator\">:</span> <span class=\"token string\">\"\"</span><span class=\"token punctuation\">,</span>\n    address<span class=\"token operator\">:</span> <span class=\"token string\">\"\"</span>\n\n<span class=\"token punctuation\">}</span>\n\nmodule<span class=\"token punctuation\">.</span>exports <span class=\"token operator\">=</span> Object<span class=\"token punctuation\">.</span><span class=\"token function\">create</span><span class=\"token punctuation\">(</span>Contact<span class=\"token punctuation\">)</span></code></pre></div>\n<p>Um ponto importante sobre domínios de aplicação é que eles não devem guardar informações que não sejam referentes ao seu domínio. Parece óbvio essa ideia porém como visto no exemplo acima temos um objeto <strong>Contato</strong> porém existe nele um campo chamado <code class=\"language-text\">id</code> que poderia ser usado por um banco de dados contudo não agrega valor ao domínio <strong>Contato</strong>, a primeira coisa seria excluí-lo. A segunda coisa que podemos usar para nos ajudar a manipular os dados do nosso domínio é ter uma forma de criarmos o objeto, uma função criadora que receba os dados de um contato e devolva uma instância pronta. Há algumas formas de fazer porém aqui iremos usar um <strong>construtor</strong>, uma função que toda classe já possui no <strong>JavaScript</strong> e já é responsável por criar o objeto.</p>\n<p>Para podermos usar um <strong>construtor</strong> é necessário algumas alterações no objeto <strong>Contato</strong>:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">Contact</span> <span class=\"token punctuation\">{</span>\n\n    <span class=\"token function\">constructor</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">name<span class=\"token punctuation\">,</span> telephone<span class=\"token punctuation\">,</span> address</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>name <span class=\"token operator\">=</span> name\n        <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>telephone <span class=\"token operator\">=</span> telephone\n        <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>address <span class=\"token operator\">=</span> address\n    <span class=\"token punctuation\">}</span>\n\n<span class=\"token punctuation\">}</span>\n\nmodule<span class=\"token punctuation\">.</span>exports <span class=\"token operator\">=</span> Contact</code></pre></div>\n<p>Agora tiramos o campo <code class=\"language-text\">id</code> do domínio e alteramos o objeto <strong>Contato</strong> para que ele seja uma classe, com um construtor e três variáveis que são informadas no momento da criação.</p>\n<p>Vamos usar a classe <strong>Contato</strong>, porém onde seria o lugar mais apropriado para isso?</p>\n<p>Podemos delegar para a camada da nossa aplicação que é responsável por executar a lógica, a camada <strong>Service</strong>. Faz sentido pois nessa camada executamos as regras que são pertinentes e salvamos no banco de dados, então bem que podemos fazer esse tratamento lá.</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> Contact <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'../model'</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">Service</span><span class=\"token punctuation\">{</span>\n\n    <span class=\"token function\">constructor</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">repository</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>repository <span class=\"token operator\">=</span> repository\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token function\">create</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">body</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">const</span> contact <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Contact</span><span class=\"token punctuation\">(</span>body<span class=\"token punctuation\">.</span>name<span class=\"token punctuation\">,</span> body<span class=\"token punctuation\">.</span>telephone<span class=\"token punctuation\">,</span> body<span class=\"token punctuation\">.</span>address<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>repository<span class=\"token punctuation\">.</span><span class=\"token function\">insert</span><span class=\"token punctuation\">(</span>contact<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n    \n    <span class=\"token keyword\">async</span> <span class=\"token function\">getById</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">name</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">const</span> contact <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>repository<span class=\"token punctuation\">.</span><span class=\"token function\">selectById</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">)</span>\n\n        <span class=\"token keyword\">return</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Contact</span><span class=\"token punctuation\">(</span>contact<span class=\"token punctuation\">.</span>name<span class=\"token punctuation\">,</span> contact<span class=\"token punctuation\">.</span>telephone<span class=\"token punctuation\">,</span> contact<span class=\"token punctuation\">.</span>address<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n    \n    <span class=\"token keyword\">async</span> <span class=\"token function\">getAll</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">const</span> contactList <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>repository<span class=\"token punctuation\">.</span><span class=\"token function\">selectAll</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n        <span class=\"token keyword\">const</span> result <span class=\"token operator\">=</span> contactList<span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">contact</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">return</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Contact</span><span class=\"token punctuation\">(</span>contact<span class=\"token punctuation\">.</span>name<span class=\"token punctuation\">,</span> contact<span class=\"token punctuation\">.</span>telephone<span class=\"token punctuation\">,</span> contact<span class=\"token punctuation\">.</span>address<span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n        <span class=\"token keyword\">return</span> result\n    <span class=\"token punctuation\">}</span>\n    \n    <span class=\"token keyword\">async</span> <span class=\"token function\">put</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">name<span class=\"token punctuation\">,</span> body</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">const</span> contact <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>repository<span class=\"token punctuation\">.</span><span class=\"token function\">update</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">,</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Contact</span><span class=\"token punctuation\">(</span>body<span class=\"token punctuation\">.</span>name<span class=\"token punctuation\">,</span> body<span class=\"token punctuation\">.</span>telephone<span class=\"token punctuation\">,</span> body<span class=\"token punctuation\">.</span>address<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\n        <span class=\"token keyword\">const</span> result <span class=\"token operator\">=</span> contact<span class=\"token punctuation\">.</span>value\n\n        <span class=\"token keyword\">return</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Contact</span><span class=\"token punctuation\">(</span>result<span class=\"token punctuation\">.</span>name<span class=\"token punctuation\">,</span> result<span class=\"token punctuation\">.</span>telephone<span class=\"token punctuation\">,</span> result<span class=\"token punctuation\">.</span>address<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">async</span> <span class=\"token function\">patch</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">name<span class=\"token punctuation\">,</span> body</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>repository<span class=\"token punctuation\">.</span><span class=\"token function\">patch</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">,</span> body<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    \n    <span class=\"token function\">remove</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">name</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>repository<span class=\"token punctuation\">.</span><span class=\"token function\">remove</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n\n<span class=\"token punctuation\">}</span>\n\nmodule<span class=\"token punctuation\">.</span>exports <span class=\"token operator\">=</span> Service</code></pre></div>\n<p>No código acima para cada ponto que precisamos inserir ou recuperar os dados da aplicação iremos usar a classe <strong>Contato</strong> para mantermos o padrão de domínio.</p>\n<p>Para ficar mais claro iremos fazer as requisições para a API e ver as respostas.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">curl</span> --location --request POST <span class=\"token string\">'http://localhost:3000/api'</span> <span class=\"token punctuation\">\\</span>\n--header <span class=\"token string\">'Content-Type: application/json'</span> <span class=\"token punctuation\">\\</span>\n--data-raw <span class=\"token string\">'{\n    \n    \"name\": \"Kelly\",\n    \"telephone\": \"1199999999\",\n    \"address\": \"Rua dos Bobos n 2\"\n\n}'</span> <span class=\"token operator\">|</span> json_pp</code></pre></div>\n<p>E temos como resposta o seguinte:</p>\n<div class=\"gatsby-highlight\" data-language=\"json\"><pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n    <span class=\"token property\">\"name\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Kelly\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"telephone\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"1199999999\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"address\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Rua dos Bobos n 2\"</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Podemos notar que não existe mais um campo <code class=\"language-text\">id</code>, apesar de internamente existir e ser importante para o banco de dados para o nosso domínio e para a nossa resposta ao usuário que fez essa chamada não é.</p>\n<h2 id=\"Adicionando-validacao\" style=\"position:relative;\">Adicionando validação<a href=\"#Adicionando-validacao\" aria-label=\"Adicionando validacao permalink\" class=\"anchor after\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a></h2>\n<p>A nossa aplicação ainda não é capaz de validar a entrada de dados. Validar entrada de dados é algo que pode começar simples e logo se torna muito complicado dependendo das regras, para nos ajudar com isso existe uma biblioteca especializada nisso, o <strong>JOI</strong>, onde conseguimos definir regras a serem seguidas. Validar entrada de dados é algo que pode ser muito complicado e o <strong>JOI</strong> possui uma vasta <a href=\"https://joi.dev/api/?v=17.4.0\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">documentação</a> para nos ajudar com regras, desde as mais simples até as mais complexas usando <strong>Regex</strong>.</p>\n<p>Em conjunto com o <strong>JOI</strong>, que faz a validação dos dados que estão entrando na aplicação precisamos devolver uma resposta clara e padronizada ao usuário sobre o erro ocorrido. Para isso usaremos o <em>middleware</em> <strong>Celebrate</strong> que integra muito bem ao <strong>JOI</strong>.</p>\n<p>Precisamos adicionar somente o <strong>Celebrate</strong> ao projeto, pois o <strong>JOI</strong> é usado internamente pelo <strong>Celebrate</strong>:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">npm</span> <span class=\"token function\">install</span> --save celebrate</code></pre></div>\n<p>E vamos começar criando a parte da nossa aplicação que será responsável por fazer as validações, vamos criar um pasta chamada <strong>validation</strong> e nela criamos o arquivo <code class=\"language-text\">index.js</code>:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> Joi <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'celebrate'</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">const</span> bodySchema <span class=\"token operator\">=</span> Joi<span class=\"token punctuation\">.</span><span class=\"token function\">object</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">keys</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n    name<span class=\"token operator\">:</span> Joi<span class=\"token punctuation\">.</span><span class=\"token function\">string</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">min</span><span class=\"token punctuation\">(</span><span class=\"token number\">3</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">required</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    telephone<span class=\"token operator\">:</span> Joi<span class=\"token punctuation\">.</span><span class=\"token function\">string</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">required</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>  \n    address<span class=\"token operator\">:</span> Joi<span class=\"token punctuation\">.</span><span class=\"token function\">string</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">required</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">const</span> pathSchema <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> name<span class=\"token operator\">:</span> Joi<span class=\"token punctuation\">.</span><span class=\"token function\">string</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">min</span><span class=\"token punctuation\">(</span><span class=\"token number\">3</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">required</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span> \n\nmodule<span class=\"token punctuation\">.</span>exports <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n    bodySchema<span class=\"token punctuation\">,</span>\n    pathSchema\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Definimos as seguintes validações:</p>\n<ul>\n<li>Quando for passado um <em>body</em> são obrigatórios todos os campos e o campo <code class=\"language-text\">name</code> deve ter pelo menos 3 caracteres.</li>\n<li>Quando for passado um <em>pathParam</em> de nome <code class=\"language-text\">name</code>, ele é obrigatório e deve ter pelo menos 3 caracteres.</li>\n</ul>\n<p>Agora precisamos adicionar essas validações nas rotas, mas antes disso para que o <strong>Celebrate</strong> possa lidar com as mensagens de erro é necessário adicioná-lo como <em>middleware</em> para o <strong>Express</strong>:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> express <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'express'</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">const</span> app <span class=\"token operator\">=</span> <span class=\"token function\">express</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">const</span> bodyParser <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'body-parser'</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">const</span> router <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'./router'</span><span class=\"token punctuation\">)</span>\n<span class=\"token comment\">//Declaração do middleware de erros do Celebrate</span>\n<span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> errors <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'celebrate'</span><span class=\"token punctuation\">)</span>\n\napp<span class=\"token punctuation\">.</span><span class=\"token function\">use</span><span class=\"token punctuation\">(</span>bodyParser<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\napp<span class=\"token punctuation\">.</span><span class=\"token function\">use</span><span class=\"token punctuation\">(</span>bodyParser<span class=\"token punctuation\">.</span><span class=\"token function\">urlencoded</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> extended<span class=\"token operator\">:</span> <span class=\"token boolean\">true</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\napp<span class=\"token punctuation\">.</span><span class=\"token function\">use</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">req<span class=\"token punctuation\">,</span> resp<span class=\"token punctuation\">,</span> next</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    resp<span class=\"token punctuation\">.</span><span class=\"token function\">set</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Access-Control-Allow-Origin'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'*'</span><span class=\"token punctuation\">)</span>\n    <span class=\"token function\">next</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\napp<span class=\"token punctuation\">.</span><span class=\"token function\">use</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/api'</span><span class=\"token punctuation\">,</span> router<span class=\"token punctuation\">)</span>\n\n<span class=\"token comment\">//Inclusão do middleware</span>\napp<span class=\"token punctuation\">.</span><span class=\"token function\">use</span><span class=\"token punctuation\">(</span><span class=\"token function\">errors</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">const</span> server <span class=\"token operator\">=</span> app<span class=\"token punctuation\">.</span><span class=\"token function\">listen</span><span class=\"token punctuation\">(</span><span class=\"token number\">3000</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'A API está funcionando!'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\nmodule<span class=\"token punctuation\">.</span>exports <span class=\"token operator\">=</span> server</code></pre></div>\n<p>E após podemos adicionar as validações nas rotas:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> celebrate<span class=\"token punctuation\">,</span> Segments <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'celebrate'</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">const</span> validation <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'../validation'</span><span class=\"token punctuation\">)</span>\n\nrouter<span class=\"token punctuation\">.</span><span class=\"token function\">post</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/'</span><span class=\"token punctuation\">,</span> <span class=\"token function\">celebrate</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">[</span>Segments<span class=\"token punctuation\">.</span><span class=\"token constant\">BODY</span><span class=\"token punctuation\">]</span><span class=\"token operator\">:</span> validation<span class=\"token punctuation\">.</span>bodySchema <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">req<span class=\"token punctuation\">,</span> res</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> contact <span class=\"token operator\">=</span> req<span class=\"token punctuation\">.</span>body\n\n    service<span class=\"token punctuation\">.</span><span class=\"token function\">create</span><span class=\"token punctuation\">(</span>contact<span class=\"token punctuation\">)</span>\n\n    res<span class=\"token punctuation\">.</span><span class=\"token function\">status</span><span class=\"token punctuation\">(</span><span class=\"token number\">201</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span>contact<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\nrouter<span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/:name'</span><span class=\"token punctuation\">,</span> <span class=\"token function\">celebrate</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">[</span>Segments<span class=\"token punctuation\">.</span><span class=\"token constant\">PARAMS</span><span class=\"token punctuation\">]</span><span class=\"token operator\">:</span> validation<span class=\"token punctuation\">.</span>pathSchema <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">req<span class=\"token punctuation\">,</span> res</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n\n    <span class=\"token keyword\">const</span> id <span class=\"token operator\">=</span> req<span class=\"token punctuation\">.</span>name_from_param\n\n    <span class=\"token keyword\">const</span> result <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> service<span class=\"token punctuation\">.</span><span class=\"token function\">getById</span><span class=\"token punctuation\">(</span>id<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>result <span class=\"token operator\">!==</span> <span class=\"token keyword\">undefined</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n        res<span class=\"token punctuation\">.</span><span class=\"token function\">status</span><span class=\"token punctuation\">(</span><span class=\"token number\">200</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span>result<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span>\n    <span class=\"token punctuation\">}</span>\n    \n    res<span class=\"token punctuation\">.</span><span class=\"token function\">sendStatus</span><span class=\"token punctuation\">(</span><span class=\"token number\">204</span><span class=\"token punctuation\">)</span>\n    \n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>As funções de rotas do <strong>Express</strong> podem receber um argumento que é um <strong>handler</strong> e no nosso caso será o <strong>Celebrate</strong> juntamente com a validação do <strong>JOI</strong>.</p>\n<p>Na função <em>celebrate</em> é passado um objeto onde a chave é o segmento, <strong>Segments</strong>, que deve ser validado, no nosso exemplo validamos tanto o <em>body</em> com o <strong>Segments.BODY</strong> e o <em>pathParam</em> com o <strong>Segments.PARAMS</strong>; e o valor é a validação que deve ser aplicada.</p>\n<p>Com isso podemos testar a API, primeiramente com <strong>POST</strong>:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">curl</span> --location --request POST <span class=\"token string\">'http://localhost:3000/api'</span> <span class=\"token punctuation\">\\</span>\n--header <span class=\"token string\">'Content-Type: application/json'</span> <span class=\"token punctuation\">\\</span>\n--data-raw <span class=\"token string\">'{\n    \n    \"name\": \"Kelly\",\n    \"address\": \"Rua dos Bobos n 2\"\n\n}'</span> <span class=\"token operator\">|</span> json_pp</code></pre></div>\n<p>E teremos a seguinte validação:</p>\n<div class=\"gatsby-highlight\" data-language=\"json\"><pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n    <span class=\"token property\">\"statusCode\"</span><span class=\"token operator\">:</span> <span class=\"token number\">400</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"error\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Bad Request\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"message\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"celebrate request validation failed\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"validation\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token property\">\"body\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token property\">\"source\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"body\"</span><span class=\"token punctuation\">,</span>\n            <span class=\"token property\">\"keys\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\n                <span class=\"token string\">\"telephone\"</span>\n            <span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n            <span class=\"token property\">\"message\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"\\\"telephone\\\" is required\"</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>E agora com um <strong>GET</strong>:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">curl</span> --location --request GET <span class=\"token string\">'http://localhost:3000/api/k'</span></code></pre></div>\n<p>E como resposta teremos:</p>\n<div class=\"gatsby-highlight\" data-language=\"json\"><pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n    <span class=\"token property\">\"statusCode\"</span><span class=\"token operator\">:</span> <span class=\"token number\">400</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"error\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Bad Request\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"message\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"celebrate request validation failed\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"validation\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token property\">\"params\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token property\">\"source\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"params\"</span><span class=\"token punctuation\">,</span>\n            <span class=\"token property\">\"keys\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\n                <span class=\"token string\">\"name\"</span>\n            <span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n            <span class=\"token property\">\"message\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"\\\"name\\\" length must be at least 3 characters long\"</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h2 id=\"Conclusao\" style=\"position:relative;\">Conclusão<a href=\"#Conclusao\" aria-label=\"Conclusao permalink\" class=\"anchor after\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a></h2>\n<p>Nesse artigo foi apresentado como podemos deixar a nossa aplicação um pouco mais coerente através de uma especificação de domínio e inserir validações que nos ajudam a proteger a aplicação de inserção de dados errados ou consultas desnecessárias.</p>\n<h2 id=\"Codigo-do-projeto\" style=\"position:relative;\">Código do projeto<a href=\"#Codigo-do-projeto\" aria-label=\"Codigo do projeto permalink\" class=\"anchor after\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a></h2>\n<p>O código desse artigo está no <a href=\"https://github.com/guilhermegarcia86/phonebook/tree/feature/validation\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">GitHub</a>.</p>","fields":{"slug":"/express-celebrate-joi/"},"frontmatter":{"date":"27 de abril de 2021","description":"Utilizando Celebrate e Joi para validações","title":"Validando endpoints com NodeJS","tags":["JavaScript","NodeJS","Express","Celebrate","Joi","Validação"],"author":"Guilherme Alves","image":{"id":"977b7753-1817-5bbd-81a6-5e20d456312b","publicURL":"/static/a5935ca36776cba2ebe24350aecb97cd/capa-express-celebrate-joi.png","childImageSharp":{"fluid":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABT0lEQVQoz5VS207CQBTs3/oJ/oaPvpmY+EQMRiVEgwkqBdMLhZbGavRJa6FQ0hqotHR37G4llIopns3J2bOXmcnsCoQQWM8vEBUV7dsumjcdaN0envqPEJsPaHf6iOMELCilKAshXi7RupNxdnqBWu0alcolGlctNO5FHFROcF6tYxFF/DAjZ6D5LBIJa+w529pgmyMpVVQEF3jDBgVPpsL+sDF2x5gFn3i3bbiuC8dxYKfz4XDIe1Z/KaRc4SZDGIaQZRmKokBKq2ma0DSNV0mSMBgMoOs6DMPA12KxVkkyDCEvfeXTZDJBEATwPA+WZcH3fU7E+ul0yhW6oxGiOOZ34ihI7/SKHu72ittCTn/Jm+tsAub9KMtlQvjZI3GMvcMOqqKa7RUV/gVeXEtINq/rHvaPVbyOwh+76HbAXYIU7Fn1/wbMVK9B+FfLqf8GmA5PuQbZl0QAAAAASUVORK5CYII=","aspectRatio":1.7777777777777777,"src":"/static/a5935ca36776cba2ebe24350aecb97cd/0823f/capa-express-celebrate-joi.png","srcSet":"/static/a5935ca36776cba2ebe24350aecb97cd/c67b7/capa-express-celebrate-joi.png 320w,\n/static/a5935ca36776cba2ebe24350aecb97cd/d3930/capa-express-celebrate-joi.png 640w,\n/static/a5935ca36776cba2ebe24350aecb97cd/0823f/capa-express-celebrate-joi.png 1280w,\n/static/a5935ca36776cba2ebe24350aecb97cd/c730b/capa-express-celebrate-joi.png 1920w,\n/static/a5935ca36776cba2ebe24350aecb97cd/55bfe/capa-express-celebrate-joi.png 2240w","sizes":"(max-width: 1280px) 100vw, 1280px"}}}},"timeToRead":7}},"pageContext":{"slug":"/express-celebrate-joi/","previous":{"fields":{"slug":"/express-rest-db/"},"frontmatter":{"title":"Express e MongoDB","date":"19 abr, 2021"}},"next":{"fields":{"slug":"/nestjs-fastify-typeorm/"},"frontmatter":{"title":"Criando uma aplicação REST com NestJS, Fastify e TypeORM","date":"01 jun, 2021"}}}},"staticQueryHashes":["63159454"]}