<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Vinicius Reis</title>
    <description>The latest articles on Forem by Vinicius Reis (@vinicius73).</description>
    <link>https://forem.com/vinicius73</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F29841%2F42ca614b-3e57-4c31-a9fc-b33654a4cfa5.jpeg</url>
      <title>Forem: Vinicius Reis</title>
      <link>https://forem.com/vinicius73</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/vinicius73"/>
    <language>en</language>
    <item>
      <title>Funções Puras e imutabilidade, um pouco sobre código limpo e qualidade</title>
      <dc:creator>Vinicius Reis</dc:creator>
      <pubDate>Mon, 16 Sep 2019 20:28:37 +0000</pubDate>
      <link>https://forem.com/codecasts/funcoes-puras-e-imutabilidade-um-pouco-sobre-codigo-limpo-e-qualidade-2he3</link>
      <guid>https://forem.com/codecasts/funcoes-puras-e-imutabilidade-um-pouco-sobre-codigo-limpo-e-qualidade-2he3</guid>
      <description>&lt;p&gt;Código limpo (&lt;em&gt;clean code&lt;/em&gt;) é um tópico recorrente e importante. Infelizmente não há uma adoção tão grande quanto se imagina ou espera.&lt;/p&gt;

&lt;p&gt;Entre as motivações estão a falta de aprofundamento do tópico e suas nuances, bem como uma boa contextualização e a realidade dos projetos ou empresas onde os profissionais de desenvolvimento de software trabalham.&lt;br&gt;
O caos, a cobrança e demanda, muitos líderes ou gerentes não conseguem, ou simplesmente não veem valor nessas práticas, o bom e velho &lt;em&gt;“o importante é funcionar”&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Talvez algumas pessoas fiquem chocadas ou surpresas ao saber que ainda há muitas empresas e profissionais não sigam práticas e conceitos consideradas por muitos básicas.&lt;/p&gt;

&lt;p&gt;Este artigo visa ajudar a desmistificar alguns tópicos e técnicas, facilitando a adoção das mesmas.&lt;/p&gt;


&lt;h2&gt;
  
  
  Clean Code e JavaScript
&lt;/h2&gt;

&lt;p&gt;Clean Code é um assunto extenso, até mesmo controverso em alguns aspectos. Algumas coisas podem ser consideradas subjetivas, debates não são raros.&lt;/p&gt;

&lt;p&gt;Infelizmente muitos desses debates são &lt;a href="https://pt.wikipedia.org/wiki/Lei_da_trivialidade" rel="noopener noreferrer"&gt;bikeshedding&lt;/a&gt;, resultam em nada. Quando isto acontece, quem esta na posição de liderança do time precisa tomar uma postura rígida e clara, algumas vezes unilaterais. Não é algo simples, afinal pode gerar conflitos no time, porém, é algo necessário.&lt;/p&gt;

&lt;p&gt;Meu conselho é: seja honesto e claro, a intenção não é impor uma vontade, mas sim encerrar diálogos improdutivos.&lt;/p&gt;
&lt;h3&gt;
  
  
  Ferramental
&lt;/h3&gt;

&lt;p&gt;Muitas dessas discussões são sobre ponto e vírgula… Tabs ou espaços… &lt;a href="https://pt.wikipedia.org/wiki/CamelCase" rel="noopener noreferrer"&gt;CamelCase&lt;/a&gt; ou &lt;a href="https://en.wikipedia.org/wiki/Snake_case" rel="noopener noreferrer"&gt;Snake Case&lt;/a&gt;… A solução é simples, adotar um estilo pré existente e consolidado e seguir com ele sem nenhuma alteração.&lt;/p&gt;

&lt;p&gt;No JavaScript possuímos alguns padrões já bastante populares: &lt;a href="https://google.github.io/styleguide/jsguide.html" rel="noopener noreferrer"&gt;Google Style Guide&lt;/a&gt;, &lt;a href="https://github.com/airbnb/javascript" rel="noopener noreferrer"&gt;Airbnb Style Guide&lt;/a&gt; e &lt;a href="https://standardjs.com/" rel="noopener noreferrer"&gt;JavaScript Standard Style&lt;/a&gt;. Todos possuem suas regras para o &lt;a href="https://eslint.org/" rel="noopener noreferrer"&gt;ESLint&lt;/a&gt;. Escolha um deles e adote para seu time ou projeto, recomendo não fazer modificações nas regras.&lt;/p&gt;

&lt;p&gt;Há plataformas que vão além do que o ESLint faz, analisando e classificando seu código. Algumas são gratuitas para projetos open-source.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://deepscan.io/home/" rel="noopener noreferrer"&gt;DeepScan&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.sonarsource.com/products/codeanalyzers/sonarjs.html" rel="noopener noreferrer"&gt;SonarJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://prepack.io/" rel="noopener noreferrer"&gt;Prepack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.codefactor.io/" rel="noopener noreferrer"&gt;CodeFactor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codeclimate.com/" rel="noopener noreferrer"&gt;Code Climate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.codacy.com/" rel="noopener noreferrer"&gt;Codacy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codebeat.co/" rel="noopener noreferrer"&gt;Codebeat&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.sonarqube.org/" rel="noopener noreferrer"&gt;SonarQube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Técnicas
&lt;/h3&gt;

&lt;p&gt;São várias, este artigo vai se focar em &lt;a href="https://www.sitepoint.com/immutability-javascript/" rel="noopener noreferrer"&gt;&lt;strong&gt;Imutabilidade&lt;/strong&gt;&lt;/a&gt; e &lt;a href="https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-pure-function-d1c076bec976" rel="noopener noreferrer"&gt;&lt;strong&gt;Funções Puras&lt;/strong&gt;&lt;/a&gt;. Porém, não podemos deixar de citar algumas como &lt;a href="https://pt.wikipedia.org/wiki/Don%27t_repeat_yourself" rel="noopener noreferrer"&gt;DRY&lt;/a&gt;, &lt;a href="https://pt.wikipedia.org/wiki/SOLID" rel="noopener noreferrer"&gt;SOLID&lt;/a&gt;, &lt;a href="https://pt.wikipedia.org/wiki/Keep_It_Simple" rel="noopener noreferrer"&gt;KISS&lt;/a&gt; e &lt;a href="https://eltonminetto.net/2016/06/24/como-melhorar-seus-codigos-usando-object-calisthenics/" rel="noopener noreferrer"&gt;Object Calisthenics&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ao se aprofundar nessas técnicas você perceberá a convergência de ideias e fluxos, com o tempo e prática elas se tornaram naturais ao seu estilo de codificação.&lt;/p&gt;


&lt;h2&gt;
  
  
  Imutabilidade
&lt;/h2&gt;

&lt;p&gt;Imutabilidade talvez seja um dos tópicos mais complexos deste artigo. Não uma complexidade técnica, mas uma complexidade quase filosófica e de alguma &lt;em&gt;falsos positivos&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A primeira coisa que devemos entender, imutabilidade não significa constante.&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;73&lt;/span&gt;
&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;37&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5eme2dfcibd021zxqiwe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5eme2dfcibd021zxqiwe.png" alt="js const error"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Este é o erro que recebemos ao executar o exemplo anterior, muitos vão assumir que &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;const&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; no JavaScript esta relacionado a constante, porém seu objetivo é impedir a &lt;strong&gt;reatribuição&lt;/strong&gt; de uma variável.&lt;/p&gt;

&lt;p&gt;Vamos entender um pouco mais como isso funciona.&lt;/p&gt;

&lt;h2&gt;
  
  
  Valores e Referências
&lt;/h2&gt;

&lt;p&gt;Em JavaScript temos os seguintes primitivos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/pt-BR/docs/Glossario/Booleano" rel="noopener noreferrer"&gt;Boolean&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/pt-BR/docs/Glossario/N%C3%BAmero" rel="noopener noreferrer"&gt;Number&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/pt-BR/docs/Glossario/String" rel="noopener noreferrer"&gt;String&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/pt-BR/docs/Glossario/Nulo" rel="noopener noreferrer"&gt;Null&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/pt-BR/docs/Glossario/Undefined" rel="noopener noreferrer"&gt;Undefined&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Symbol" rel="noopener noreferrer"&gt;Symbol&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quando usamos os operadores de comparação &lt;code&gt;==&lt;/code&gt; e &lt;code&gt;===&lt;/code&gt; internamente e em resumo, estamos comparando referências de memória. JavaScript é uma linguagem 100% orientada a objetos, todos os seus tipos e valores são objetos.&lt;/p&gt;

&lt;p&gt;Objetos vão possui um endereço de memória, na prática &lt;code&gt;x == y&lt;/code&gt; esta comparando se o endereço de memória que &lt;code&gt;x&lt;/code&gt; representa, é o mesmo que &lt;code&gt;y&lt;/code&gt; representa. Por isso que &lt;code&gt;{} == {}&lt;/code&gt; ou &lt;code&gt;[] == []&lt;/code&gt; não funciona, pois cada &lt;code&gt;{}&lt;/code&gt; e &lt;code&gt;[]&lt;/code&gt; apontam para locais diferentes da memória.&lt;/p&gt;

&lt;p&gt;Sabendo que &lt;code&gt;2&lt;/code&gt; é do tipo Number e também um objeto, como &lt;code&gt;2 == 2&lt;/code&gt; funciona? A resposta é simples, os tipos primitivos em JavaScript são constantes e imutáveis.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;01&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;73&lt;/span&gt;
&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;73&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="mi"&gt;03&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;37&lt;/span&gt;
&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;73&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Na linha &lt;code&gt;01.&lt;/code&gt; declaramos &lt;code&gt;n&lt;/code&gt; e atribuímos &lt;code&gt;73&lt;/code&gt; para ele.&lt;/li&gt;
&lt;li&gt;Na linha &lt;code&gt;02.&lt;/code&gt; comparamos &lt;code&gt;n == 73&lt;/code&gt;, como &lt;code&gt;n&lt;/code&gt; aponta para o mesmo endereço de memória que &lt;code&gt;73&lt;/code&gt; temos &lt;code&gt;true&lt;/code&gt; como resultado.&lt;/li&gt;
&lt;li&gt;Na linha &lt;code&gt;03.&lt;/code&gt; reatribuímos &lt;code&gt;n&lt;/code&gt; a outro valor, agora &lt;code&gt;37&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;Na linha &lt;code&gt;04.&lt;/code&gt; comparamos &lt;code&gt;n == 73&lt;/code&gt;, como &lt;code&gt;n&lt;/code&gt; aponta para outro endereço e não para &lt;code&gt;73&lt;/code&gt;, temos &lt;code&gt;false&lt;/code&gt; como resultado.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Todo primitivo em JavaScript se comporta dessa maneira, outra característica relacionada a este comportamento é a imutabilidade deles, métodos de um primitivo não modificam seu valor… não alteram sua referência na memória, quando necessário geram novas referências, mas nunca modificam a original.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;s1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Codecasts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;s2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;s1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// CODECASTS&lt;/span&gt;
&lt;span class="nx"&gt;s1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;s2&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este comportamento é nativo dos primitivos, porém outros tipos como &lt;code&gt;Array&lt;/code&gt; e &lt;code&gt;Object&lt;/code&gt; não se comportam dessa maneira, &lt;code&gt;[7, 3] == [7, 3]&lt;/code&gt; sempre será &lt;code&gt;false&lt;/code&gt;, pois cada um aponta para um endereço de memória diferente.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://medium.com/p/explaining-value-vs-reference-in-javascript-647a975e12a0" rel="noopener noreferrer"&gt;Explaining Value vs. Reference in Javascript&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Referências Imutáveis
&lt;/h2&gt;

&lt;p&gt;Quando estamos falando de imutabilidade em JavaScript estamos falando em &lt;em&gt;evitar modificar referências&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Ao usar &lt;code&gt;const&lt;/code&gt; em primitivos já estamos garantindo uma boa parcela de imutabilidade, porém o maior desafio é trabalhar com objetos e listas imutáveis.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;01&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;           &lt;span class="c1"&gt;// arr --&amp;gt; [7, 3, 12]&lt;/span&gt;
&lt;span class="mi"&gt;03&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unshift&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;         &lt;span class="c1"&gt;// arr --&amp;gt; [1, 7, 3, 12]&lt;/span&gt;
&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;last&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// arr --&amp;gt; [1, 7, 3]&lt;/span&gt;
&lt;span class="mi"&gt;05&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;last&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Refs: &lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/push" rel="noopener noreferrer"&gt;&lt;code&gt;.push&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift" rel="noopener noreferrer"&gt;&lt;code&gt;.unshift&lt;/code&gt;&lt;/a&gt; e &lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/pop" rel="noopener noreferrer"&gt;&lt;code&gt;.pop&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Na linha &lt;code&gt;01.&lt;/code&gt; declaramos &lt;code&gt;arr&lt;/code&gt;, atribuímos nele um array &lt;code&gt;[7, 3]&lt;/code&gt;. Nas linhas &lt;code&gt;02.&lt;/code&gt; a &lt;code&gt;04.&lt;/code&gt; manipulamos &lt;code&gt;arr&lt;/code&gt; e em seguida é ilustrado seu estado atual.&lt;/p&gt;

&lt;p&gt;Inicialmente coisas assim podem parecer inofensivas, mas há um potencial de cenários extremamente difíceis de serem identificados ou &lt;strong&gt;rastreados&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O próximo exemplo ilustra como objetos são usados como referência.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função &lt;code&gt;fn&lt;/code&gt; não faz nada além de retornar &lt;code&gt;x&lt;/code&gt; seu único argumento. Ao comparar &lt;code&gt;obj == fn(obj)&lt;/code&gt; temos &lt;code&gt;true&lt;/code&gt; como resultado, pois estamos retornando a mesma instância/referência.&lt;/p&gt;

&lt;p&gt;O exemplo abaixo explora brevemente os impactos desse comportamento.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setPrice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;73&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Instant Kung Foo.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;setPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;73&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função &lt;code&gt;setPrice&lt;/code&gt; recebe &lt;code&gt;product&lt;/code&gt; e adiciona ou modifica a propriedade &lt;code&gt;price&lt;/code&gt;, isso fica claro quando comparamos &lt;code&gt;product.price == 73&lt;/code&gt;. Isso se chama &lt;strong&gt;efeito colateral (&lt;em&gt;side effect&lt;/em&gt;)&lt;/strong&gt;, a função &lt;code&gt;setPrice&lt;/code&gt; é uma &lt;strong&gt;função impura&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setPrice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;73&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Instant Kung Foo.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newProduct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;73&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="nx"&gt;newProduct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;73&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora a função &lt;code&gt;setPrice&lt;/code&gt; retorna uma &lt;a href="https://we-are.bookmyshow.com/understanding-deep-and-shallow-copy-in-javascript-13438bad941c" rel="noopener noreferrer"&gt;&lt;strong&gt;cópia rasa&lt;/strong&gt; &lt;/a&gt;&lt;strong&gt;(&lt;em&gt;shallow copy&lt;/em&gt;)&lt;/strong&gt; de &lt;code&gt;product&lt;/code&gt; que recebeu como argumento, acrescentando ou modificando a propriedade &lt;code&gt;price&lt;/code&gt;. Esse procedimento obriga a criação de uma &lt;strong&gt;nova variável&lt;/strong&gt; &lt;code&gt;newProduct&lt;/code&gt;, isso acontece pois &lt;code&gt;const&lt;/code&gt; foi utilizado, o próximo exemplo usa &lt;code&gt;let&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Este fluxo pode incomodar um pouco, normalmente esta abordagem não é necessária, usa-se técnicas como &lt;a href="https://medium.com/front-end-weekly/pipe-and-compose-in-javascript-5b04004ac937" rel="noopener noreferrer"&gt;pipe e compose&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Funções Puras
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://medium.com/@jamesjefferyuk/javascript-what-are-pure-functions-4d4d5392d49c" rel="noopener noreferrer"&gt;Funções puras (pure functions)&lt;/a&gt; andam ao lado da imutabilidade, na prática podemos dizer que uma não existe sem a outra.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Entende-se como pura a função que sempre devolve o mesmo resultado para um mesmo argumento, não importando a quantidade de vezes que ela é chamada, sem causar efeitos coletareis (side effects).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Parece e é obvio, porém, infelizmente ainda causa dúvidas para alguns programadores. Essa técnica exige um pouco de esforço por parte do programador, ele tem que explicitamente optar por usa-la.&lt;br&gt;
Vajamos o seguinte exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// impure.js&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addToCounter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// pure.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este é um dos primeiros exemplos usados para descrever uma função impura, é bem óbvio. Porém sua simplicidade também dificulta sua adoção, sabemos que um programa real é mais complexo do que essa função.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
    &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O exemplo anterior é mais próximo a uma aplicação &lt;em&gt;real&lt;/em&gt;. Temos a função &lt;code&gt;request&lt;/code&gt; que recebe &lt;code&gt;params&lt;/code&gt;, caso &lt;code&gt;params.client&lt;/code&gt; exista, &lt;code&gt;params&lt;/code&gt; é modificado.&lt;/p&gt;

&lt;p&gt;A função &lt;code&gt;request&lt;/code&gt; gera um efeito colateral gravíssimo, é impossível determinar a instabilidade e consequentemente &lt;em&gt;bugs&lt;/em&gt; que essa função causa para quem a chamar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
    &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com esta mudança o problema foi resolvido, &lt;code&gt;params&lt;/code&gt; não é mais modificado, o procedimento agora é aplicado a uma cópia dele. Porém, ainda há como melhorar esta função.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parseRequestParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
    &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseRequestParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Toda a lógica de tratamento dos parâmetros foi isolada em &lt;code&gt;parseRequestParams&lt;/code&gt;. A função passa a ser mais objetiva, delegando parte da lógica a outra função, uma função mais especializada. Isso não apenas melhora a leitura como permite criar testes de unidade com maior cobertura de possibilidades.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Uma linha, um comando, uma função.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A função &lt;code&gt;parseRequestParams&lt;/code&gt; ainda pode evoluir ao utilizar técnicas com &lt;strong&gt;&lt;em&gt;pipe&lt;/em&gt;&lt;/strong&gt; e &lt;strong&gt;&lt;em&gt;compose&lt;/em&gt;&lt;/strong&gt;. A biblioteca &lt;a href="https://ramdajs.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;ramda&lt;/strong&gt;&lt;/a&gt; fornece essas e várias funções úteis para ajudar na implementação dessas técnicas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;compose&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;omit&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ramda&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parseClientInRequestParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nf"&gt;omit&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;client_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parseUserInRequestParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nf"&gt;omit&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parseRequestParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;compose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parseClientInRequestParams&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parseUserInRequestParams&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As funções &lt;code&gt;parseClientInRequestParams&lt;/code&gt; e &lt;code&gt;parseUserInRequestParams&lt;/code&gt; ficaram muito similares, podemos simplifica-las.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;compose&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;omit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ramda&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createParseEntityInRequestParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nf"&gt;omit&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_id`&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parseClientInRequestParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createParseEntityInRequestParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parseUserInRequestParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createParseEntityInRequestParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função &lt;code&gt;createParseEntityinRequestParams&lt;/code&gt; retorna uma função que funciona exatamente como as implementações anteriores de &lt;code&gt;parseClientInRequestParams&lt;/code&gt; e &lt;code&gt;parseUserInRequestParams&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Receber e retornar funções só é possível pois funções são &lt;a href="https://en.wikipedia.org/wiki/First-class_function" rel="noopener noreferrer"&gt;Cidadãos de Primeira-Classe (First-class citizens)&lt;/a&gt; no JavaScript, são tratadas como valores.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Com o tempo mais padrões desses vão surgindo e se torna natural o uso de funções puras e &lt;a href="https://medium.com/javascript-scene/javascript-factory-functions-with-es6-4d224591a8b1" rel="noopener noreferrer"&gt;factory functions&lt;/a&gt;. É um nível de reuso muito grande e de extrema flexibilidade.&lt;/p&gt;

&lt;h3&gt;
  
  
  Encapsulando Fluxos Impuros
&lt;/h3&gt;

&lt;p&gt;Infelizmente não é viável criar uma aplicação que não lide com fluxos impuros. Operações que dependem de &lt;em&gt;i/o&lt;/em&gt;, &lt;em&gt;disco&lt;/em&gt;, &lt;em&gt;rede&lt;/em&gt;, &lt;em&gt;banco de dados&lt;/em&gt;… São operações com impuras e muitas vezes vão produzir efeitos colaterais.&lt;/p&gt;

&lt;p&gt;Quando falamos de programação funcional, não é raro termos como &lt;a href="https://en.wikipedia.org/wiki/Monad_(functional_programming)" rel="noopener noreferrer"&gt;&lt;em&gt;monads&lt;/em&gt;&lt;/a&gt; aparecerem. Eles dão origem a muita confusão, em especial para quem ainda esta apenas começando com programação funcional.&lt;/p&gt;

&lt;p&gt;Este artigo não vai tratar de &lt;em&gt;monads&lt;/em&gt;, e sim de uma abordagem simplista para essas situações.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseRequestParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reaproveitando o exemplo anterior, temos a função &lt;code&gt;request&lt;/code&gt;. Por mais que ela não gera mais um efeito colateral direto ela retorna uma &lt;a href="https://developers.google.com/web/fundamentals/primers/promises?hl=pt-br" rel="noopener noreferrer"&gt;promessa&lt;/a&gt;. Existe uma discussão sobre a “pureza” de uma função que retorna uma promessa, a verdade é que ela poderá ter &lt;a href="https://medium.com/@aidobreen/js-promises-async-await-and-functional-programming-f2e5fa66b4ef" rel="noopener noreferrer"&gt;resultados diferentes&lt;/a&gt; mesmo que os argumentos sejam os mesmos, isso torna ela uma &lt;a href="https://medium.com/@aidobreen/js-promises-async-await-and-functional-programming-f2e5fa66b4ef" rel="noopener noreferrer"&gt;&lt;strong&gt;função impura&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Sendo ela uma função pura ou não, há um problema mais “grave”, o fato dessa função depender de &lt;code&gt;http&lt;/code&gt; para funcionar. Assumimos que &lt;code&gt;http&lt;/code&gt; é uma global, provavelmente uma instância do &lt;a href="https://github.com/axios/axios" rel="noopener noreferrer"&gt;axios&lt;/a&gt;. Justamente por ser global que temos um problema na hora de testar esta função.&lt;/p&gt;

&lt;p&gt;Depender de estados globais prejudica muito o processo de testes, pois é necessário recriar toda uma camada de ambiente para que o teste seja possível, além de usar técnicas sofisticadas de &lt;a href="https://sinonjs.org/" rel="noopener noreferrer"&gt;mocking&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A solução é simples, injetar &lt;code&gt;http&lt;/code&gt; em &lt;code&gt;request&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseRequestParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso pode ser particularmente verboso na hora de utilizar, porém com técnicas de injeção de dependências isso passa a ser simples e prático. Os links abaixo demonstram algumas técnicas que vão ajudar.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.codecasts.com.br/dependency-injection-container-javascript-49e9eb2c399c" rel="noopener noreferrer"&gt;Container de Injeção de Dependências com JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.codecasts.com.br/dependency-injection-em-http-middlewares-node-js-91bed97fc955" rel="noopener noreferrer"&gt;Injeção de Serviços em Middlewares HTTP no Node.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/sD94szvFqGw"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;p&gt;Este artigo possui um objetivo &lt;strong&gt;subliminar&lt;/strong&gt;, introduzir o leitor a programação funcional sem que ele perceba. Todo o conteúdo aqui apresentado faz parte das técnicas e fluxos de programação funcional com JavaScript.&lt;/p&gt;

&lt;p&gt;Quando se fala de programação funcional muito se fala de &lt;a href="https://pt.wikipedia.org/wiki/C%C3%A1lculo_lambda" rel="noopener noreferrer"&gt;&lt;em&gt;lambda&lt;/em&gt;&lt;/a&gt;, &lt;a href="https://pt.wikipedia.org/wiki/Functor" rel="noopener noreferrer"&gt;&lt;em&gt;functors&lt;/em&gt;&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=cB0vpg9-YMQ" rel="noopener noreferrer"&gt;&lt;em&gt;monads&lt;/em&gt;&lt;/a&gt; e outros termos… Programação funcional possui diversas camadas e convive bem com outros paradigmas.&lt;/p&gt;

&lt;p&gt;Seguir os princípios da programação funcional é uma das melhores maneiras de se obter um código limpo e de qualidade.&lt;/p&gt;

&lt;p&gt;Em minha concepção pessoal um código de qualidade é um código testável. Talvez a maior dificuldade em se implementar testes seja justamente escrever código testável. Imutabilidade e funções puras são os primeiros passos.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/bVfHSc38dLU"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;p&gt;Este artigo foi originalmente postado em &lt;a href="https://blog.codecasts.com.br/pure-finctions-immutability-clean-code-quality-31825b0d7516" rel="noopener noreferrer"&gt;2018-12-30, no Medium&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Se quiser saber mais sobre meu trabalho visite &lt;a href="https://dev.to/codecasts"&gt;&lt;strong&gt;dev.to/codecasts&lt;/strong&gt;&lt;/a&gt; ou  &lt;a href="https://blog.codecasts.com.br/" rel="noopener noreferrer"&gt;&lt;strong&gt;blog.codecasts.com.br&lt;/strong&gt;&lt;/a&gt;. Assine nosso &lt;a href="https://www.youtube.com/channel/UCTluPqMkm90zyw6mCde561A" rel="noopener noreferrer"&gt;canal no YouTube&lt;/a&gt;, lá você vai ver vídeos sobre &lt;a href="https://www.youtube.com/watch?v=fBInMy61plk&amp;amp;t=0s&amp;amp;list=PLy5T05I_eQYNQs4Pta85XRSucm3IOHx2M&amp;amp;index=2" rel="noopener noreferrer"&gt;JavaScript&lt;/a&gt;, &lt;a href="https://www.youtube.com/playlist?index=1&amp;amp;list=PLy5T05I_eQYN8T15w4KLLcDcjAmIXDyu-&amp;amp;playnext=1" rel="noopener noreferrer"&gt;jQuery&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=eukZI7Rcrss&amp;amp;t=0s&amp;amp;index=2&amp;amp;list=PLy5T05I_eQYPl_iF2aJ0T0JBgJMatOLwv" rel="noopener noreferrer"&gt;Gulp&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=yRr8Wo4XfYY&amp;amp;list=PLy5T05I_eQYOoUz2TtAqq35RLCc-xBZCe&amp;amp;index=2&amp;amp;t=0s" rel="noopener noreferrer"&gt;ES6&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=ck8uNY0B0HI&amp;amp;index=2&amp;amp;t=0s&amp;amp;list=PLy5T05I_eQYOr3uPSI-eTVCLe1GF1qOf5" rel="noopener noreferrer"&gt;Vue.JS&lt;/a&gt; e muito mais. Também não deixe de entrar em contato pelo nosso grupo no &lt;a href="https://t.me/codecasters" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>codequality</category>
      <category>functional</category>
      <category>ptbr</category>
    </item>
    <item>
      <title>Escalando e performando aplicações Node.js</title>
      <dc:creator>Vinicius Reis</dc:creator>
      <pubDate>Sat, 14 Sep 2019 21:13:41 +0000</pubDate>
      <link>https://forem.com/codecasts/escalando-e-performando-aplicacoes-node-js-2j20</link>
      <guid>https://forem.com/codecasts/escalando-e-performando-aplicacoes-node-js-2j20</guid>
      <description>&lt;p&gt;Hoje Node.js é uma das &lt;a href="https://insights.stackoverflow.com/survey/2018#technology-_-frameworks-libraries-and-tools"&gt;plataformas de desenvolvimento&lt;/a&gt; mais utilizadas no mundo. Seu ecossistema é vasto e poderoso e sua performance não é nada ruim.&lt;/p&gt;

&lt;p&gt;Como não existe bala de prata, Node.js possui pontos de atenção, características que quando não observadas podem prejudicar a performance de aplicações criadas com ele.&lt;/p&gt;

&lt;h2&gt;
  
  
  Single Tread e código bloqueante
&lt;/h2&gt;

&lt;p&gt;Muitos já devem saber, porém, é importante frisar, Node.js é single tread, mesmo que existam operações async (obrigado &lt;a href="https://libuv.org/"&gt;libuv&lt;/a&gt;) , algumas operações são consideradas bloqueantes e travam toda e qualquer execução de código.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6T8y6Kod--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/o7q9za0x0mwygtl4zjxu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6T8y6Kod--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/o7q9za0x0mwygtl4zjxu.png" alt="https://repl.it/@vinicius73/blocking-code"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://repl.it/@vinicius73/blocking-code"&gt;Neste exemplo&lt;/a&gt;, usamos o &lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/API/console/time"&gt;&lt;code&gt;console.time&lt;/code&gt;&lt;/a&gt; para contabilizar a execução de alguns trechos de código.&lt;/p&gt;

&lt;p&gt;Há basicamente duas operações neste código, uma assíncrona com &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout"&gt;&lt;code&gt;setTimeout&lt;/code&gt;&lt;/a&gt;, e outra síncrona, na implementação da função &lt;code&gt;sleep&lt;/code&gt;. A parte assíncrona deste código deveria ser executada em 1 segundo, porém no resultado dos &lt;em&gt;timers&lt;/em&gt; , o código só executou depois de 3 segundos, depois que a parte síncrona do código executou.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Para entender melhor este comportamento, leia sobre &lt;a href="https://medium.com/reactbrasil/como-o-javascript-funciona-o-event-loop-e-o-surgimento-da-programa%C3%A7%C3%A3o-ass%C3%ADncrona-5-maneiras-de-18d0b8d6849a"&gt;event loop&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Isso aconteceu, pois a &lt;em&gt;tread&lt;/em&gt; do Node/JS ficou &lt;em&gt;travada&lt;/em&gt; em uma única operação, uma &lt;strong&gt;operação bloqueante&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Operações bloqueantes
&lt;/h3&gt;

&lt;p&gt;No exemplo anterior foi possível ter uma ideia entender que &lt;code&gt;while&lt;/code&gt; é uma operação bloqueante e qual o impacto desse tipo de operação na aplicação. Além do &lt;code&gt;while&lt;/code&gt; outras estruturas e funções também são bloqueantes. &lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Statements/for"&gt;for&lt;/a&gt;,  &lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach"&gt;Array.prototype.forEach&lt;/a&gt;, &lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/map"&gt;Array.prototype.map&lt;/a&gt;, &lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce"&gt;Array.prototype.reduce&lt;/a&gt; entre outras.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Podemos assumir que todo loop é uma operação bloqueante.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Uma única operação bloqueante tem um enorme potencial destrutivo em uma aplicação http.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DLfkS1_z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/skh4o5658clij2tunz59.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DLfkS1_z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/skh4o5658clij2tunz59.png" alt="http server"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Um servidor http extremamente simples, para testar sua performance a ferramenta &lt;a href="https://github.com/JoeDog/siege"&gt;siege&lt;/a&gt; será utilizada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;siege http://localhost:7337/ &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; 10s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2rqja9ON--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/747hqp14qtmyigkew7jd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2rqja9ON--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/747hqp14qtmyigkew7jd.png" alt="Siege Result Normal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Durante 10 segundos o servidor http foi capaz de receber &lt;em&gt;51.415&lt;/em&gt; requisições com correferência de 25. Abaixo alguns _logs das requisições&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--s3piuqgW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2w57e0o8w2tu7790lo8d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--s3piuqgW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2w57e0o8w2tu7790lo8d.png" alt="Http response normal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Evidentemente este é um ótimo resultado.&lt;/p&gt;

&lt;p&gt;Na próxima imagem a rota agora passa a executar uma operação bloqueante por 500ms.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_Sq67c4G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/4uk59e7sjitghqjd89wm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_Sq67c4G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/4uk59e7sjitghqjd89wm.png" alt="blocking route"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Novamente o teste de performance com o siege.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hxmrMqvi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/bunflaq4lw56bu472kcv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hxmrMqvi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/bunflaq4lw56bu472kcv.png" alt="siege result blokcing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Durante 10 segundos 25 processos concorrentes conseguiram realizar com sucesso apenas 18 requisições. É uma diminuição drástica se comparado ao teste anterior. Abaixo alguns &lt;em&gt;logs&lt;/em&gt; dos &lt;em&gt;requests&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TzGvbjxK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ybtj3ppt1cew1bf68mj7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TzGvbjxK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ybtj3ppt1cew1bf68mj7.png" alt="http response blocking"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cada requisição levou ao menos 500ms para ser respondida. É possível ver que o servidor http recebeu 43 requisições, porém, o teste terminou antes que do node concluir o processamento das requisições.&lt;/p&gt;

&lt;p&gt;O node foi capaz de resolver apenas 18 requisições em 10 segundos: &lt;code&gt;500ms * 18 = 9000ms = 9s&lt;/code&gt; Todas as outras requisições ficaram "presas".&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Este é o preço de executar operações síncronas, bloqueantes em servidores http node.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Cluster mode, múltiplos servidores.
&lt;/h2&gt;

&lt;p&gt;Mesmo que esta característica seja um problema sério, há formas eficientes de contorna-la.&lt;/p&gt;

&lt;p&gt;Node possui um módulo chamado &lt;a href="https://nodejs.org/api/cluster.html"&gt;&lt;em&gt;cluster&lt;/em&gt;&lt;/a&gt;. Este módulo permite criar forks do seu processo/servidor, atuando como um &lt;a href="https://pt.wikipedia.org/wiki/Balanceamento_de_carga"&gt;&lt;em&gt;load balancer&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Você pode aprender mais sobre este módulo &lt;a href="https://www.infoq.com/br/articles/nodejs-utilizando-modulo-de-cluster/"&gt;aqui&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Neste artigo não vamos falar diretamente do &lt;em&gt;cluster mode&lt;/em&gt;, mas de uma ferramenta que usa ele para prover uma série de recursos úteis que melhoram não só a performance como a saúde da aplicação.&lt;/p&gt;

&lt;h3&gt;
  
  
  PM2
&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://pm2.keymetrics.io/"&gt;PM2, ou &lt;em&gt;Process Manager 2&lt;/em&gt;&lt;/a&gt; é uma ferramenta indispensável na hora de colocar uma aplicação node em produção.&lt;/p&gt;

&lt;p&gt;É possível destacar dois principais recursos do PM2, dentre vários outros.&lt;/p&gt;

&lt;h4&gt;
  
  
  Monitoramento do processo
&lt;/h4&gt;

&lt;p&gt;O PM2 observa cada processo iniciado com ele, e caso o processo morra, ele mesmo reinicia o processo, sem a nenhuma intervenção humana.&lt;/p&gt;

&lt;p&gt;Este recurso é extremamente útil para garantir que a aplicação não saia do ar caso alguma exceção seja disparada e não tratada.&lt;/p&gt;

&lt;h4&gt;
  
  
  Múltiplos processos por aplicação
&lt;/h4&gt;

&lt;p&gt;Além de manter a aplicação &lt;em&gt;viva&lt;/em&gt;, o PM2 consegue subir mais de um processo por aplicação. Dessa forma contornamos os problemas citados neste artigo.&lt;/p&gt;

&lt;p&gt;Outra coisa interessante é poder subir mais de uma aplicação com o PM2. Se a aplicação http precisa de algum outro processo paralelo dando suporte, como um consumidor de filas, é possível ter total controle sobre isso.&lt;/p&gt;

&lt;h3&gt;
  
  
  PM2 em ação
&lt;/h3&gt;

&lt;p&gt;Na documentação do PM2 é possível encontrar como se instala ele e todas as suas opções de configuração. Abaixo é possível ver o resultado do PM2 sendo utilizado em &lt;em&gt;cluster mode&lt;/em&gt;, neste exemplo foram iniciados 5 processos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pm2 start index.js &lt;span class="nt"&gt;-i&lt;/span&gt; 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ciq-HYQ9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/46nj8z8zakij0huhvk7k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ciq-HYQ9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/46nj8z8zakij0huhvk7k.png" alt="siege cluster 5"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nestas condições o servidor http foi capaz de responder a 95 requisições em 10 segundos, um valor maior que os 18 do teste anterior.&lt;/p&gt;

&lt;p&gt;Agora o mesmo teste com 10 processos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pm2 start index.js &lt;span class="nt"&gt;-i&lt;/span&gt; 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Em7y8K_Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/9nxi84b6yun5nbqkdk1k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Em7y8K_Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/9nxi84b6yun5nbqkdk1k.png" alt="siege cluster 10"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora o serviço foi capaz de responder 180 requisições. O próximo exemplo será com 20 processos e em seguida com 40.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pm2 start index.js &lt;span class="nt"&gt;-i&lt;/span&gt; 20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UGTi1HYC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/r58defwwu04urzek4zxf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UGTi1HYC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/r58defwwu04urzek4zxf.png" alt="siege cluster 20"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pm2 start index.js &lt;span class="nt"&gt;-i&lt;/span&gt; 40
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xAX_U1Yl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/hsxzzxszro94iuq7tfmo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xAX_U1Yl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/hsxzzxszro94iuq7tfmo.png" alt="siege cluster 40"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com 20 foi possível dobrar a quantidade de requisições, porém, com 40 processos não. Isso acontece simplesmente porque os processos começam a concorrer cada vez mais pelo processador.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ambiente de produção
&lt;/h3&gt;

&lt;p&gt;Neste exemplo foi utilizado uma maquina com 8 núcleos de processamento e 13Gb de memória RAM. Estes valores são superiores a muitos servidores comuns. Por isso a simples escala de processos não é o suficiente, é importante ter isso em mente na hora de construir uma aplicação. Em muitos momentos é necessário utilizar de &lt;a href="https://medium.com/@pedrro/escala-ou-n%C3%A3o-escala-escalabilidade-101-parte-1-d43fe1e3143e"&gt;escala horizontal&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A quantidade de processos por núcleo de processamento do servidor é algo que varia de aplicação para aplicação, então o ideal é fazer testes e identificar como extrair o máximo da máquina sem deixa-la em &lt;em&gt;"stress"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Soluções como &lt;em&gt;&lt;a href="http://comunidadecloud.com/post/auto-scaling/"&gt;auto scaling&lt;/a&gt;&lt;/em&gt; + &lt;a href="https://www.redhat.com/pt-br/topics/containers/what-is-docker"&gt;docker&lt;/a&gt; são altamente recomendadas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Mesmo Node.js sendo single-tread é possivel tirar proveito dos vários núcleos do processador. Há também um módulo para lidar com &lt;a href="https://nodejs.org/api/worker_threads.html"&gt;&lt;em&gt;treads&lt;/em&gt;&lt;/a&gt;, elevando as possibilidades.&lt;/p&gt;

&lt;p&gt;Este não é o único aspecto que deve ser levado em consideração quando se trabalha com aplicações Node.js, então não se limite a este artigo e as informações contidas aqui.&lt;/p&gt;

&lt;p&gt;Performance pura e simplesmente não é tudo, código bem escrito e testado muitas vezes são mais importantes. Até a forma como a aplicação é colocada em produção é importante.&lt;/p&gt;

&lt;p&gt;Ao focar em entregar algo de qualidade, seguindo boas práticas de escrita e organização muitas coisas relacionadas a performance são resolvidas logo no começo.&lt;/p&gt;




&lt;p&gt;Se quiser saber mais sobre meu trabalho visite &lt;a href="https://dev.to/codecasts"&gt;&lt;strong&gt;dev.to/codecasts&lt;/strong&gt;&lt;/a&gt; ou  &lt;a href="https://blog.codecasts.com.br/"&gt;&lt;strong&gt;blog.codecasts.com.br&lt;/strong&gt;&lt;/a&gt;. Assine nosso &lt;a href="https://www.youtube.com/channel/UCTluPqMkm90zyw6mCde561A"&gt;canal no YouTube&lt;/a&gt;, lá você vai ver vídeos sobre &lt;a href="https://www.youtube.com/watch?v=fBInMy61plk&amp;amp;t=0s&amp;amp;list=PLy5T05I_eQYNQs4Pta85XRSucm3IOHx2M&amp;amp;index=2"&gt;JavaScript&lt;/a&gt;, &lt;a href="https://www.youtube.com/playlist?index=1&amp;amp;list=PLy5T05I_eQYN8T15w4KLLcDcjAmIXDyu-&amp;amp;playnext=1"&gt;jQuery&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=eukZI7Rcrss&amp;amp;t=0s&amp;amp;index=2&amp;amp;list=PLy5T05I_eQYPl_iF2aJ0T0JBgJMatOLwv"&gt;Gulp&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=yRr8Wo4XfYY&amp;amp;list=PLy5T05I_eQYOoUz2TtAqq35RLCc-xBZCe&amp;amp;index=2&amp;amp;t=0s"&gt;ES6&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=ck8uNY0B0HI&amp;amp;index=2&amp;amp;t=0s&amp;amp;list=PLy5T05I_eQYOr3uPSI-eTVCLe1GF1qOf5"&gt;Vue.JS&lt;/a&gt; e muito mais. Também não deixe de entrar em contato pelo nosso grupo no &lt;a href="https://t.me/codecasters"&gt;Telegram&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>performance</category>
      <category>ptbr</category>
    </item>
    <item>
      <title>Mantendo projetos Node/JS atualizados</title>
      <dc:creator>Vinicius Reis</dc:creator>
      <pubDate>Tue, 02 Apr 2019 20:22:48 +0000</pubDate>
      <link>https://forem.com/codecasts/mantendo-projetos-node-js-atualizados-25l8</link>
      <guid>https://forem.com/codecasts/mantendo-projetos-node-js-atualizados-25l8</guid>
      <description>&lt;p&gt;Ter pacotes de terceiros em nosso projeto é algo comum. Porém mante-los atualizados, infelizmente, não faz parte da rotina de muitos profissionais. Negligenciar esse processo pode acarretar em muitos problemas no futuro.&lt;/p&gt;

&lt;p&gt;Este artigo trata dos motivos e estratégias como manter as dependências dos projetos sempre atualizadas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Motivação
&lt;/h2&gt;

&lt;p&gt;Software não é algo estático, esta em constante mudança e evolução. O mesmo se aplica as dependências que utilizamos em nossos projetos. E como dependências temos não apenas pacotes/código de terceiros, mas também a própria plataforma/linguagem que utilizamos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Linguagem/Plataforma
&lt;/h3&gt;

&lt;p&gt;Tão importante quanto manter a base de código atualizada, é manter a linguagem/plataforma que esta sendo utilizada atualizada.&lt;br&gt;
O node &lt;a href="https://benchmarking.nodejs.org/" rel="noopener noreferrer"&gt;monitora sua performance ao longo do tempo&lt;/a&gt;, garantindo que cada versão esta com mais performance ou que não houve regressão na performance. Sem contar todas as &lt;a href="https://hackerone.com/nodejs" rel="noopener noreferrer"&gt;brechas de segurança&lt;/a&gt; que são corrigidas a cada nova versão.&lt;/p&gt;

&lt;p&gt;Isso significa que manter o Node.js atualizado fornece mais performance e segurança.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pacotes de terceiros
&lt;/h3&gt;

&lt;p&gt;Manter o projeto atualizado garante que o projeto não irá sofrer com esse bugs e potenciais falhas de segurança. Além de potenciais ajustes que melhoram a performance de alguma coisa do pacote.&lt;/p&gt;

&lt;p&gt;É importante lembrar que pacotes também tem dependências, elas também podem e precisam ser atualizadas.&lt;br&gt;
Identificar que um pacote esta com suas dependências desatualizadas, é uma boa possibilidade de contribuição. Não é incomum brechas de segurança justamente em cenários como esses.&lt;/p&gt;

&lt;p&gt;O NPM mantém uma lista de &lt;a href="https://www.npmjs.com/advisories" rel="noopener noreferrer"&gt;vulnerabilidades detectadas&lt;/a&gt; além do próprio npm possuir um &lt;a href="https://docs.npmjs.com/cli/audit" rel="noopener noreferrer"&gt;recurso que analisa o package.json&lt;/a&gt; do projeto em busca de problemas. o Yarn possui um &lt;a href="https://yarnpkg.com/lang/en/docs/cli/audit/" rel="noopener noreferrer"&gt;recurso similar&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Também é possível usar ferramentas que verificam automaticamente e constantemente o projeto.&lt;br&gt;
O &lt;a href="https://snyk.io/" rel="noopener noreferrer"&gt;snyk.io&lt;/a&gt; é uma delas, com suporte a várias linguagens.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequência
&lt;/h2&gt;

&lt;p&gt;Em um mundo ideal todos os dias os projetos seriam verificados sobre possíveis atualizações.&lt;br&gt;
Porém não são todos os projetos que possuem recursos para usar ferramentas que automaticamente analisam isso, como &lt;a href="https://greenkeeper.io/" rel="noopener noreferrer"&gt;greenkeeper.io&lt;/a&gt; e &lt;a href="https://renovatebot.com/" rel="noopener noreferrer"&gt;renovatebot.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Uma forma para se manter uma boa frequência de verificações é fazer isso sempre que for mexer no projeto. Porém, há projetos que podem ficar várias semanas sem uma modificação. Para esses casos uma rotina recorrente de verificações é necessária.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Talvez um tarefa da &lt;em&gt;sprint&lt;/em&gt; só para isso, a cada 15 dias.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Break changes, quebra de versão, incompatibilidades...
&lt;/h2&gt;

&lt;p&gt;Não é incomum as dependências de um projeto mudarem de tal forma que seja necessário alguma mudança no código do projeto, um processo de migração ou adequação.&lt;br&gt;
Em geral é o maior problema com atualizações, porém há formas de se lidar com quebras de versões.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Manter a frequência de verificação de atualizações garante um baixo acumulo de atualizações, e com isso uma maior facilidade de lidar com essas quebras.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Versionamento Semântico (Semantic Version)
&lt;/h3&gt;

&lt;p&gt;A melhor forma de avaliar a compatibilidade entre as versões de uma ferramenta é o &lt;a href="https://semver.org/lang/pt-BR/" rel="noopener noreferrer"&gt;semver&lt;/a&gt;.&lt;br&gt;
Dependências que seguem essa metodologia de versionamento deixam clara a compatibilidade entre suas versões. É necessário cuidado com ferramentas que não seguem esse modelo de versionamento, pois é impossível prever possíveis incompatibilidades.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;

Dado um número de versão MAJOR.MINOR.PATCH, incremente a:
&lt;span class="p"&gt;
1.&lt;/span&gt;  versão Maior(MAJOR): quando fizer mudanças incompatíveis na API,
&lt;span class="p"&gt;2.&lt;/span&gt;  versão Menor(MINOR): quando adicionar funcionalidades mantendo compatibilidade, e
&lt;span class="p"&gt;3.&lt;/span&gt;  versão de Correção(PATCH): quando corrigir falhas mantendo compatibilidade.

Rótulos adicionais para pré-lançamento(pre-release) e metadados de construção(build) estão disponíveis como extensão ao formato MAJOR.MINOR.PATCH.&lt;span class="sb"&gt;


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Changelogs / Release Notes
&lt;/h3&gt;

&lt;p&gt;É a melhor forma de documentar a evolução de um pacote ou ferramenta ao longo do tempo. &lt;em&gt;Changelogs&lt;/em&gt; mantém um histórico de mudanças, além de possíveis quebras de versão. É importantíssimo sempre verificar essas anotações quando se atualiza alguma dependência. &lt;br&gt;
Algumas dependências além do &lt;em&gt;changelog&lt;/em&gt;, mantém um &lt;em&gt;release notes&lt;/em&gt; (notas de lançamento) para cada nova versão. As vezes esse &lt;em&gt;release notes&lt;/em&gt; é usado apenas em caso de mudanças mais expressivas.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Com base nesses documentos, é possível não apenas prevenir de quebras de versões inconvenientes, como também saber de novos recursos que podem ser relevantes ao projeto.  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Quando há uma quebra de versão que impacte o projeto, nem sempre é algo que possa ser modificado/ajustado naquele momento. Porém, ao obter essa informação é possível se programar para faze-lo em outro momento mais propício. &lt;/p&gt;

&lt;p&gt;Se você é um mantenedor de algum pacote, não deixe de gerar &lt;a href="https://keepachangelog.com/pt-BR/1.0.0/" rel="noopener noreferrer"&gt;changelogs&lt;/a&gt;, no minimo documente os &lt;em&gt;releases&lt;/em&gt; de novas versões.&lt;br&gt;
Há ferramentas criadas para ajudar nesse processo.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/github-tools/github-release-notes" rel="noopener noreferrer"&gt;github-tools/github-release-notes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/CookPete/auto-changelog" rel="noopener noreferrer"&gt;CookPete/auto-changelog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/release-it/release-it" rel="noopener noreferrer"&gt;release-it/release-it&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Testes Automatizados
&lt;/h4&gt;

&lt;p&gt;Testes ainda serão a melhor forma de garantir que ao atualizar alguma dependência o projeto continuará funcionando como o previsto. A necessidade de se manter o projeto atualizado e livre de riscos só reforçam essa necessidade.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Testes automatizados infelizmente não são uma realidade para muitos profissionais e empresas, por diversos motivos.&lt;br&gt;
Não é o objetivo deste artigo se aprofundar neste tópico, porém uma dica pode ser dada: focar o esforço em aprender a escrever código testável, esta sim é a maior dificuldade de quem ainda não sabe como trabalhar com testes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;
  
  
  Como atualizar as dependências
&lt;/h1&gt;

&lt;p&gt;Não é necessário  verificar manualmente dependência por dependência. Tanto o &lt;a href="https://yarnpkg.com/lang/en/docs/cli/upgrade/" rel="noopener noreferrer"&gt;yarn&lt;/a&gt; quanto o &lt;a href="https://docs.npmjs.com/cli/update.html" rel="noopener noreferrer"&gt;npm&lt;/a&gt; possuem ferramental para isso.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

yarn upgrade
npm update


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;O yarn possui mais opções para esse processo&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

yarn upgrade &lt;span class="nt"&gt;--scope&lt;/span&gt; @vue &lt;span class="nt"&gt;--latest&lt;/span&gt;
yarn upgrade left-pad &lt;span class="nt"&gt;--pattern&lt;/span&gt; &lt;span class="s2"&gt;"gulp|grunt"&lt;/span&gt;
yarn upgrade-interactive
yarn upgrade-interactive &lt;span class="nt"&gt;--latest&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;O mais interessante é o &lt;a href="https://yarnpkg.com/en/docs/cli/upgrade-interactive" rel="noopener noreferrer"&gt;&lt;code&gt;yarn upgrade-interactive&lt;/code&gt;&lt;/a&gt; seguido do argumento &lt;code&gt;--latest&lt;/code&gt;. Esta combinação exibe uma lista interativa com as últimas versões disponíveis das dependências do &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnwp9spxbh9h1xqdwelcn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnwp9spxbh9h1xqdwelcn.png"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Se quiser saber mais sobre meu trabalho visite &lt;a href="https://dev.to/codecasts"&gt;&lt;strong&gt;dev.to/codecasts&lt;/strong&gt;&lt;/a&gt; ou  &lt;a href="https://blog.codecasts.com.br/" rel="noopener noreferrer"&gt;&lt;strong&gt;blog.codecasts.com.br&lt;/strong&gt;&lt;/a&gt;. Assine nosso &lt;a href="https://www.youtube.com/channel/UCTluPqMkm90zyw6mCde561A" rel="noopener noreferrer"&gt;canal no YouTube&lt;/a&gt;, lá você vai ver vídeos sobre &lt;a href="https://www.youtube.com/watch?v=fBInMy61plk&amp;amp;t=0s&amp;amp;list=PLy5T05I_eQYNQs4Pta85XRSucm3IOHx2M&amp;amp;index=2" rel="noopener noreferrer"&gt;JavaScript&lt;/a&gt;, &lt;a href="https://www.youtube.com/playlist?index=1&amp;amp;list=PLy5T05I_eQYN8T15w4KLLcDcjAmIXDyu-&amp;amp;playnext=1" rel="noopener noreferrer"&gt;jQuery&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=eukZI7Rcrss&amp;amp;t=0s&amp;amp;index=2&amp;amp;list=PLy5T05I_eQYPl_iF2aJ0T0JBgJMatOLwv" rel="noopener noreferrer"&gt;Gulp&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=yRr8Wo4XfYY&amp;amp;list=PLy5T05I_eQYOoUz2TtAqq35RLCc-xBZCe&amp;amp;index=2&amp;amp;t=0s" rel="noopener noreferrer"&gt;ES6&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=ck8uNY0B0HI&amp;amp;index=2&amp;amp;t=0s&amp;amp;list=PLy5T05I_eQYOr3uPSI-eTVCLe1GF1qOf5" rel="noopener noreferrer"&gt;Vue.JS&lt;/a&gt; e muito mais. Também não deixe de entrar em contato pelo nosso grupo no &lt;a href="https://t.me/codecasters" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>npm</category>
      <category>yarn</category>
    </item>
    <item>
      <title>Entendendo o que é GraphQL através de exemplos</title>
      <dc:creator>Vinicius Reis</dc:creator>
      <pubDate>Mon, 01 Apr 2019 20:35:03 +0000</pubDate>
      <link>https://forem.com/codecasts/entendendo-o-que-e-graphql-atraves-de-exemplos-1gn5</link>
      <guid>https://forem.com/codecasts/entendendo-o-que-e-graphql-atraves-de-exemplos-1gn5</guid>
      <description>&lt;p&gt;Mesmo com a popularidade do GraphQL, dúvidas sobre o que ele é, e o que resolve são comuns. Neste artigo pretendo explicar a partir de exemplos o que é GraphQL e qual o seu objetivo.&lt;/p&gt;




&lt;h1&gt;
  
  
  O que não é GraphQL?
&lt;/h1&gt;

&lt;p&gt;Talvez este não seja o tópico que você esperava encontrar, e algumas das coisas aqui pareçam absurdas, mas acredite há pessoas que pensam ou já pensaram isso sobre GraphQL.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://blog.codecasts.com.br/entendendo-o-que-%C3%A9-graphql-atrav%C3%A9s-de-exemplos-c2fa35e8bf63" rel="noopener noreferrer"&gt;Publicado originalmente em 10/03/2019&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  GraphQL não é um banco de dados
&lt;/h2&gt;

&lt;p&gt;GraphQL não tem nenhuma relação com o banco de dados, e não é um &lt;a href="https://en.wikipedia.org/wiki/Object-relational_mapping" rel="noopener noreferrer"&gt;ORM&lt;/a&gt;. Ele nem precisa de um banco de dados para funcionar.&lt;br&gt;
Talvez essa associação exista quando se ouve que ele é uma &lt;a href="https://en.wikipedia.org/wiki/Query_language" rel="noopener noreferrer"&gt;Query Language&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  GraphQL não é um &lt;em&gt;framework&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Não se trata de mais um &lt;em&gt;framework&lt;/em&gt;, em sua essência GraphQL é uma especificação que possui &lt;a href="https://graphql.org/code/" rel="noopener noreferrer"&gt;implementações em diversas linguagens&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  GraphQL não é exclusivo para HTTP/APIs
&lt;/h2&gt;

&lt;p&gt;GraphQL não é simplesmente uma nova forma de se criar APIs com HTTP.&lt;br&gt;&lt;br&gt;
Na verdade ele nem usa verbos HTTP, ele desconhece completamente esta camada. GraphQL não se limita ao contexto de aplicações HTTP.&lt;/p&gt;




&lt;h1&gt;
  
  
  O que é GraphQL?
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;‘Uma Query Language.’&lt;/em&gt;&lt;br&gt;&lt;br&gt;
Infelizmente é uma resposta simples e pouco objetiva. Mesmo que GraphQL em si seja algo simples, por vários motivos a explicação do que ele é não é a mais simples.&lt;/p&gt;

&lt;p&gt;O objetivo deste artigo não é entrar nas nuances mais técnicas, porém é necessário explicar alguns conceitos chave.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tipos e Schema
&lt;/h2&gt;

&lt;p&gt;GraphQL é estaticamente tipado, tudo nele precisa de um tipo associado, e esses tipos formam um &lt;em&gt;schema&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
É a partir desse &lt;em&gt;schema&lt;/em&gt; que as &lt;em&gt;queries&lt;/em&gt; são executadas e consequentemente validadas, tanto entrada quanto saída.&lt;/p&gt;

&lt;p&gt;Há alguns tipos base, como  &lt;a href="https://graphql.org/learn/schema/#scalar-types" rel="noopener noreferrer"&gt;&lt;code&gt;String&lt;/code&gt;, &lt;code&gt;Int&lt;/code&gt;, &lt;code&gt;Float&lt;/code&gt;, &lt;code&gt;ID&lt;/code&gt; e &lt;code&gt;Boolean&lt;/code&gt;&lt;/a&gt;. Eles são conhecidos como &lt;em&gt;Scalar Types&lt;/em&gt;, e é possível criar os seus próprios tipos, escalares e objetos.&lt;/p&gt;

&lt;p&gt;Segue o exemplo da criação de dois tipos, &lt;strong&gt;User&lt;/strong&gt; e &lt;strong&gt;Address&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs7dz46anxqg9w3vmxk93.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs7dz46anxqg9w3vmxk93.png" width="696" height="872"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Os tipos acompanhados de &lt;code&gt;!&lt;/code&gt; informam que não aceitam &lt;code&gt;null&lt;/code&gt; como valor.&lt;br&gt;&lt;br&gt;
O mais interessante deste exemplo é o &lt;em&gt;field&lt;/em&gt; &lt;strong&gt;&lt;em&gt;address&lt;/em&gt;&lt;/strong&gt; de &lt;strong&gt;User&lt;/strong&gt;, ele aponta para outro tipo, o &lt;strong&gt;Address&lt;/strong&gt;. Podemos assumir que há um relacionamento entre &lt;strong&gt;User&lt;/strong&gt; e &lt;strong&gt;Address&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Como esse relacionamento é feito? Não importa, GraphQL não entrega detalhes de implementação, o &lt;em&gt;field&lt;/em&gt; &lt;em&gt;address&lt;/em&gt;, pode vir de qualquer lugar seja, outro banco, arquivo ou API.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para que consultas sejam feitas, há um tipo especial no &lt;em&gt;schema&lt;/em&gt;, ele é a “porta de entrada”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbvxcdy5kvftjc0i5wg47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbvxcdy5kvftjc0i5wg47.png" width="800" height="889"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aqui temos uma idéia mais completa e elaborada. Em &lt;em&gt;schema&lt;/em&gt; informamos que o tipo &lt;strong&gt;Query&lt;/strong&gt; é responsável pela &lt;em&gt;“entrada”&lt;/em&gt; das queries, este tipo também costuma ser conhecido como &lt;strong&gt;RootQuery&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Em &lt;strong&gt;Query&lt;/strong&gt; temos dois &lt;em&gt;fields&lt;/em&gt;, &lt;strong&gt;&lt;em&gt;Users&lt;/em&gt;&lt;/strong&gt; e &lt;strong&gt;&lt;em&gt;User&lt;/em&gt;&lt;/strong&gt;. Podemos ver também o uso de argumentos em &lt;em&gt;fields&lt;/em&gt;, significa que para consumir aquele dado, é necessário passar esses argumentos caso eles sejam obrigatórias.&lt;/p&gt;

&lt;p&gt;Apenas &lt;strong&gt;&lt;em&gt;User&lt;/em&gt;&lt;/strong&gt; tem &lt;strong&gt;&lt;em&gt;uuid&lt;/em&gt;&lt;/strong&gt; com argumento obrigatório, em &lt;strong&gt;&lt;em&gt;Users,&lt;/em&gt;&lt;/strong&gt; &lt;strong&gt;&lt;em&gt;pagination&lt;/em&gt;&lt;/strong&gt; e &lt;strong&gt;&lt;em&gt;search&lt;/em&gt;&lt;/strong&gt; não são obrigatórios.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu47dxwwdgn4a90445lo9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu47dxwwdgn4a90445lo9.png" width="800" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Neste exemplo de &lt;em&gt;query&lt;/em&gt; o recurso &lt;strong&gt;&lt;em&gt;User&lt;/em&gt;&lt;/strong&gt; é consumido, passando como argumento &lt;strong&gt;&lt;em&gt;uuid&lt;/em&gt;&lt;/strong&gt;. Com base na assinatura do &lt;em&gt;field&lt;/em&gt;, se um tipo &lt;strong&gt;User&lt;/strong&gt; não for retornado, o GraphQL informará erro.&lt;/p&gt;

&lt;p&gt;Ainda no exemplo antes desse, em &lt;strong&gt;&lt;em&gt;Users&lt;/em&gt;&lt;/strong&gt;, o argumento &lt;strong&gt;&lt;em&gt;pagination&lt;/em&gt;&lt;/strong&gt; recebe também um tipo como argumento, e como resposta não temos uma lista de &lt;strong&gt;User&lt;/strong&gt;, e sim outro tipo &lt;strong&gt;UsersResource&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fejm5nnndk8vjudm39fw9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fejm5nnndk8vjudm39fw9.png" width="800" height="839"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GraphQL não tem recursos de paginação ou qualquer coisa do gênero, isso deve ser feito através do &lt;a href="https://github.com/Shopify/graphql-design-tutorial" rel="noopener noreferrer"&gt;design do &lt;em&gt;schema&lt;/em&gt;&lt;/a&gt; que está sendo criado. Este é um dos design possíveis para esse tipo de situação.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resolvers
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;A partir daqui o artigo passa a focar na &lt;a href="https://github.com/graphql/graphql-js" rel="noopener noreferrer"&gt;implementação em JavaScript&lt;/a&gt; do GraphQL, mas os conceitos são compartilhados entre as outras implementações.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Resolvers&lt;/em&gt; são funções responsáveis por, como o nome sugere, revolver um pedido e devolver o dado solicitado. Abaixo segue o exemplo de um possível resolver para &lt;strong&gt;&lt;em&gt;Query.User&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zynepwgfch8e3fildt9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zynepwgfch8e3fildt9.png" width="800" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;É uma função extremamente simples, ela recebe três argumentos: &lt;code&gt;_root_&lt;/code&gt;, &lt;code&gt;_args_&lt;/code&gt; e &lt;code&gt;_context_&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Como é um resolver raiz, &lt;em&gt;root&lt;/em&gt; não tem valor. Mais sobre ele em seguida.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O segundo parâmetro (&lt;em&gt;args&lt;/em&gt;) contém um objeto com o que foi passado para o &lt;em&gt;field&lt;/em&gt; quando a &lt;em&gt;query&lt;/em&gt; foi feita, no exemplo em questão, um objeto com a propriedade &lt;strong&gt;&lt;em&gt;uuid&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O terceiro parâmetro (&lt;em&gt;context&lt;/em&gt;) é controlado pela nossa instância do GraphQL, todos os &lt;em&gt;resolvers&lt;/em&gt; recebem o mesmo &lt;em&gt;context&lt;/em&gt;. Ele é extremamente útil para compartilhar coisas como usuário atual, serviços e coisas como conexão com o banco de dados.&lt;/p&gt;

&lt;p&gt;Neste exemplo o &lt;em&gt;uuid&lt;/em&gt; de &lt;em&gt;args&lt;/em&gt; é utilizado em conjunto do &lt;a href="https://knexjs.org/" rel="noopener noreferrer"&gt;&lt;em&gt;knex&lt;/em&gt;&lt;/a&gt; de &lt;em&gt;context&lt;/em&gt;, e com isso um registro é recuperado do banco de dados.&lt;/p&gt;

&lt;p&gt;O retorno de um &lt;em&gt;resolver&lt;/em&gt; é uma &lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Promise" rel="noopener noreferrer"&gt;promessa&lt;/a&gt;, o GraphQL espera a resolução dessas promessas para devolver os resultados obtidos. No exemplo acima, se o resultado não for satisfatório o GraphQL informa que houve um erro. Porém, é possível gerar erros mais assertivos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9609gsn0t6rjx9sxyeg8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9609gsn0t6rjx9sxyeg8.png" width="800" height="634"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora um erro mais preciso será recebido por quem executou essa &lt;em&gt;query&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Relacionamentos
&lt;/h3&gt;

&lt;p&gt;Como visto anteriormente, é possível estabelecer um relacionamento entre tipos no GraphQL. Foi estabelecido um relacionamento entre &lt;strong&gt;User&lt;/strong&gt; e &lt;strong&gt;Address&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Temos duas formas de chegar até o tipo User, através de &lt;code&gt;Query.User&lt;/code&gt;ou &lt;code&gt;Query.Users.records&lt;/code&gt;. O primeiro devolve apenas um &lt;strong&gt;User&lt;/strong&gt;, o outro uma lista de User, cada um com seu respectivo &lt;em&gt;resolver&lt;/em&gt;. Isso só tem importância para se entender que é necessário criar apenas um resolver para o &lt;em&gt;field&lt;/em&gt; &lt;strong&gt;address&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp0pisrbdm2kexxoeg7ir.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp0pisrbdm2kexxoeg7ir.png" width="800" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Este é o resolver &lt;code&gt;User.address&lt;/code&gt;. Não importa de onde o tipo User foi recuperado, há apenas um resolver para &lt;em&gt;address&lt;/em&gt;. Isso significa que uma vez que isso seja mapeado, todo o seu &lt;em&gt;schema&lt;/em&gt; tira proveito disso.&lt;/p&gt;

&lt;p&gt;Em &lt;code&gt;userAddressResolver&lt;/code&gt; &lt;strong&gt;root&lt;/strong&gt; é o &lt;strong&gt;User&lt;/strong&gt; em questão, dele é extraído a propriedade &lt;strong&gt;&lt;em&gt;zipcode&lt;/em&gt;&lt;/strong&gt;. Em seguida zipcode é passado como argumento para &lt;code&gt;zipcodeService&lt;/code&gt; . Os detalhes de implementação dele não importam, porém é possivel imaginar que este serviço se comunique com uma API externa que devolve informações baseadas no &lt;em&gt;zipcode&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Vamos acrescentar mais alguns tipos ao nosso &lt;em&gt;schema&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F46lnfvtptpm7bcs7obfs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F46lnfvtptpm7bcs7obfs.png" width="800" height="622"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora há o tipo &lt;strong&gt;Photo&lt;/strong&gt; e um novo &lt;em&gt;field&lt;/em&gt; em &lt;strong&gt;Query&lt;/strong&gt;, o &lt;strong&gt;&lt;em&gt;featuredPhotos&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Repare no field url, ele devolve o tipo &lt;strong&gt;Url&lt;/strong&gt;, este não é um tipo nativo do GraphQL, foi colocado apenas como exemplo que é possível criar tipos como esse.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Uma vez que Photo tenha um relacionamento com User, é possível fazer a seguinte &lt;em&gt;query&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz78ff16cnvkg9gohfh35.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz78ff16cnvkg9gohfh35.png" width="716" height="818"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Visão geral
&lt;/h1&gt;

&lt;p&gt;Ao adotar GraphQL em sua aplicação, você terá inicialmente uma curva levemente mais lenta no começo, porém rapidamente o valor agregado do GraphQL se destaca, o desenvolvimento do &lt;em&gt;back-end&lt;/em&gt; e do &lt;em&gt;front-end&lt;/em&gt; se torna mais ágil e dinâmico, menos idas e voltas.&lt;/p&gt;

&lt;p&gt;A maior dificuldade do GraphQL não está em sua implementação e uso, e sim no design dele. Ele não tem os problemas de design que uma aplicação &lt;a href="https://becode.com.br/o-que-e-api-rest-e-restful/" rel="noopener noreferrer"&gt;&lt;em&gt;Rest&lt;/em&gt;&lt;/a&gt; possui, porém trás novos desafios.&lt;br&gt;&lt;br&gt;
Ainda não há um consenso difundido sobre padrões de design com GraphQL, mas há uma grande fonte de exemplos e cases.&lt;/p&gt;

&lt;p&gt;Pessoalmente acredito na qualidade e versatilidade do GraphQL frente a soluções Rest. Não me sinto mais confortável em criar uma aplicação que não possua o GraphQL como API.&lt;/p&gt;

&lt;p&gt;Entre os muitos usos do GraphQL é utilizado como &lt;em&gt;front-end&lt;/em&gt; de outros &lt;em&gt;back-end&lt;/em&gt;, isso é conhecido como &lt;a href="https://medium.com/tech-tajawal/backend-for-frontend-using-graphql-under-microservices-5b63bbfcd7d9" rel="noopener noreferrer"&gt;&lt;strong&gt;Backend-For-Frontend&lt;/strong&gt;&lt;/a&gt;. Imagine a complexidade de um front-end ter que acessar várias APIs distintas para conseguir uma informação, GraphQL atende muito bem a esses cenários.&lt;/p&gt;

&lt;h1&gt;
  
  
  E o Rest?
&lt;/h1&gt;

&lt;p&gt;É possível argumentar que com a ajuda de um ORM + algum padrão mirabolante de &lt;em&gt;requests&lt;/em&gt;, é possível se obter estes resultados sem o uso do GraphQL&lt;/p&gt;

&lt;p&gt;Abaixo alguns destaques que reforçam a adoção do GraphQL&lt;/p&gt;

&lt;h2&gt;
  
  
  Existe padrão
&lt;/h2&gt;

&lt;p&gt;Na grande maioria dos casos você ou sua equipe iriam inventar algum padrão/método ou aplicar alguma biblioteca para emular esse comportamento (respostas personalizadas, relacionamentos…)&lt;br&gt;&lt;br&gt;
Porém há uma equipe grande e séria por trás da especificação do GraphQL, este artigo não cobre metade das possibilidades.&lt;/p&gt;

&lt;h2&gt;
  
  
  Auto-documentação
&lt;/h2&gt;

&lt;p&gt;Enquanto seria necessário aplicar ferramentas que geram documentações compatíveis com &lt;a href="https://swagger.io/" rel="noopener noreferrer"&gt;swagger&lt;/a&gt; e similares, GraphQL possui documentação automática, além de um ambiente de testes muito produtivo.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/graphql/graphiql" rel="noopener noreferrer"&gt;&lt;strong&gt;graphql/graphiql&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/prisma/graphql-playground" rel="noopener noreferrer"&gt;&lt;strong&gt;prisma/graphql-playground&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Auto-validação
&lt;/h2&gt;

&lt;p&gt;O sistema de tipos do GraphQL já funciona como um processo de validação, tanto de entrada quanto de saída. Também existe a possibilidade de integração com editores de código que validam as &lt;em&gt;queries&lt;/em&gt; da aplicação, além de linhas de comando que podem ser integradas em processos de CI/CD&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/prisma/vscode-graphql" rel="noopener noreferrer"&gt;&lt;strong&gt;prisma/vscode-graphql&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/cjoudrey/graphql-schema-linter" rel="noopener noreferrer"&gt;&lt;strong&gt;cjoudrey/graphql-schema-linter&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Realtime
&lt;/h2&gt;

&lt;p&gt;A especificação do GraphQL já prevê real-time. Não são todas as implementações que são compatíveis, porém ela existe e não é complexa.&lt;br&gt;&lt;br&gt;
Isso abre muitas possibilidades antes inexistentes para alguns projetos ou equipes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/facebook/graphql/blob/master/rfcs/Subscriptions.md" rel="noopener noreferrer"&gt;&lt;strong&gt;facebook/graphql&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Iniciando com GraphQL
&lt;/h1&gt;

&lt;p&gt;Este artigo não demonstra como começar com GraphQL, por isso, abaixo está uma lista de recursos úteis para se começar com GraphQL.&lt;br&gt;&lt;br&gt;
Lembrando que GraphQL é implementado em várias linguagens, então escolha a que for mais amigável para você e comece seus experimentos.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/trainingcenter/graphql-para-iniciantes-a4cbe6c3da5d" rel="noopener noreferrer"&gt;&lt;strong&gt;GraphQL para iniciantes&lt;/strong&gt; &lt;em&gt;Tudo o que você precisa saber para iniciar com GraphQL&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.howtographql.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;How to GraphQL - The Fullstack Tutorial for GraphQL&lt;/strong&gt; _Fullstack GraphQL Tutorial to go from zero to production covering all basics and advanced concepts.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/8D9XnnjFGMs"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/KaxB8wPeTkI"&gt;
&lt;/iframe&gt;
 &lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/-0uxxht4mko"&gt;
&lt;/iframe&gt;
 &lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/m26i1L2D7Yk"&gt;
&lt;/iframe&gt;
 &lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/vWdLM3IK0gw"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;




&lt;p&gt;Interessado em aprender mais sobre GraphQL? Entre no nosso grupo no Telegram &lt;a href="https://t.me/GraphQLBrasil" rel="noopener noreferrer"&gt;https://t.me/GraphQLBrasil&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Não deixe de compartilhar e comentar este artigo. Deixe nos comentários sua opinião sobre esse assunto, pontos que você concorda ou discorda. Vamos agregar mais conhecimento!&lt;/p&gt;




&lt;p&gt;Se quiser saber mais sobre meu trabalho visite &lt;a href="https://blog.codecasts.com.br" rel="noopener noreferrer"&gt;&lt;strong&gt;blog.codecasts.com.br&lt;/strong&gt;&lt;/a&gt;. Assine nosso &lt;a href="https://www.youtube.com/channel/UCTluPqMkm90zyw6mCde561A" rel="noopener noreferrer"&gt;canal no YouTube&lt;/a&gt;, lá você vai ver vídeos sobre &lt;a href="https://www.youtube.com/watch?v=fBInMy61plk&amp;amp;t=0s&amp;amp;list=PLy5T05I_eQYNQs4Pta85XRSucm3IOHx2M&amp;amp;index=2" rel="noopener noreferrer"&gt;JavaScript&lt;/a&gt;, &lt;a href="https://www.youtube.com/playlist?index=1&amp;amp;list=PLy5T05I_eQYN8T15w4KLLcDcjAmIXDyu-&amp;amp;playnext=1" rel="noopener noreferrer"&gt;jQuery&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=eukZI7Rcrss&amp;amp;t=0s&amp;amp;index=2&amp;amp;list=PLy5T05I_eQYPl_iF2aJ0T0JBgJMatOLwv" rel="noopener noreferrer"&gt;Gulp&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=yRr8Wo4XfYY&amp;amp;list=PLy5T05I_eQYOoUz2TtAqq35RLCc-xBZCe&amp;amp;index=2&amp;amp;t=0s" rel="noopener noreferrer"&gt;ES6&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=ck8uNY0B0HI&amp;amp;index=2&amp;amp;t=0s&amp;amp;list=PLy5T05I_eQYOr3uPSI-eTVCLe1GF1qOf5" rel="noopener noreferrer"&gt;Vue.JS&lt;/a&gt; e muito mais. Também não deixe de entrar em contato pelo nosso grupo no &lt;a href="https://t.me/codecasters" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;that’s all folks&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>graphql</category>
      <category>javascript</category>
      <category>api</category>
      <category>rest</category>
    </item>
  </channel>
</rss>
