<?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>DEV Community: Henrique Reis</title>
    <description>The latest articles on DEV Community by Henrique Reis (@reishenrique).</description>
    <link>https://dev.to/reishenrique</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%2F1449484%2F47e1c727-0218-4b11-8baf-f4dc65389d0d.jpeg</url>
      <title>DEV Community: Henrique Reis</title>
      <link>https://dev.to/reishenrique</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/reishenrique"/>
    <language>en</language>
    <item>
      <title>Síncrono, assíncrono e Async/Await: conectando os pontos</title>
      <dc:creator>Henrique Reis</dc:creator>
      <pubDate>Mon, 30 Mar 2026 18:17:44 +0000</pubDate>
      <link>https://dev.to/reishenrique/sincrono-assincrono-e-asyncawait-conectando-os-pontos-15g2</link>
      <guid>https://dev.to/reishenrique/sincrono-assincrono-e-asyncawait-conectando-os-pontos-15g2</guid>
      <description>&lt;p&gt;Esses dois conceitos são fundamentais para entender como o JavaScript funciona, e mais ainda, como o Node.js lida com tarefas que demoram, como requisições HTTP, acesso a banco de dados ou leitura de arquivos.&lt;/p&gt;

&lt;p&gt;No meu último post, que se tratava de como as promises realmente funcionam, citei que o próximo passo seria entender como o &lt;code&gt;async/await&lt;/code&gt; se apoiam nesse mecanismos de assíncronicidade para oferecer uma sintaxe mais legível, e hoje vou estar explicando um pouco como isso funciona.&lt;/p&gt;




&lt;h2&gt;
  
  
  O que é uma operação síncrona?
&lt;/h2&gt;

&lt;p&gt;Síncrono significa que as instruções são executadas umas após a outra, em ordem, bloqueando a execução de outras coisas até que cada etapa atual termine&lt;/p&gt;

&lt;p&gt;Uma analogia simples seria uma fila de pessoas sendo atendidas por uma única pessoa no caixa do supermercado. A próxima pessoa só será atendida depois que a anterior terminar.&lt;/p&gt;

&lt;p&gt;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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Início&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;calcularPeso&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// trava o programa até terminar&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Fim&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;Se &lt;code&gt;calcularPeso()&lt;/code&gt; levar 5 segundos, nada mais acontece durante esse tempo, o programa fica "travado". Mas na verdade o Event Loop do Node.js é travado e assim não executa mais nenhuma tarefa mas esse não é o tópico do post.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é uma operação assíncrona?
&lt;/h2&gt;

&lt;p&gt;Assíncrono significa que o programa não espera a operação terminar. Ele segue para a próxima instrução, e a operação assíncrona acontece em segundo plano, sendo executada quando possível.&lt;/p&gt;

&lt;p&gt;Uma outra pequena simples analogia seria como pedir uma pizza, você faz o pedido (assíncrono) e continua fazendo outras coisas (programa segue) e quando a pizza chega, alguém te avisa (callback/promise).&lt;/p&gt;

&lt;p&gt;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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Início&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;setTimeOut&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Operação assíncrona finalizada&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Fim&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;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Início
Fim
Operação assíncrona finalizada
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Mas porque entender isso é importante no Node.js?
&lt;/h2&gt;

&lt;p&gt;Node.js é single-threaded ou seja, existe apenas uma thread principal executando o código JavaScript (por padrão).&lt;/p&gt;

&lt;p&gt;Se você usa funções síncronas, bloqueia tudo (nenhuma requisição é atendida até a atual terminar).&lt;/p&gt;

&lt;p&gt;Com operações assíncronas, podemos escalar para milhares de coisas executando sem bloquear o Event Loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recursos assíncronos comuns:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;setTimeOut&lt;/code&gt;, &lt;code&gt;setInterval&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fetch&lt;/code&gt;, &lt;code&gt;axios&lt;/code&gt;, &lt;code&gt;request&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fs.readFile&lt;/code&gt;, &lt;code&gt;fs.writeFile&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;db.query()&lt;/code&gt; (uma consulta no banco de dados)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;socket.on()&lt;/code&gt; (eventos utilizando web socket)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Promise, async e await&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Interação de operações async com o Event Loop
&lt;/h2&gt;

&lt;p&gt;O Event loop gerencia essas operações assíncronas&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O código assíncrono é enviado para as Web APIs ou Libuv&lt;/li&gt;
&lt;li&gt;Ao finalizarem, voltam via Microtask queue (se forem Promises) ou Macrotask queue (se forem callbacks comuns)&lt;/li&gt;
&lt;li&gt;A Call Stack vai gerenciando a execução&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Conceito do await em funções assíncronas
&lt;/h3&gt;

&lt;p&gt;O await é uma palavra-chave do JavaScript usada dentro de funções assíncronas. Ela serve para esperar a resolução de uma Promise antes de continuar a execução do código, sem bloquear a thread principal do ambiente.&lt;/p&gt;

&lt;p&gt;O Node.js apesar de ser single-threaded como dito antes, é concorrente graças à sua arquitetura baseada em eventos&lt;/p&gt;

&lt;p&gt;Quando executamos uma operação de I/O, como uma consulta ao banco de dados:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const users = await db.findAll()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;O Node.js:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Dispara a operação de I/O&lt;/li&gt;
&lt;li&gt;Entrega a tarefa ao libuv, que gerencia um thread pool responsável por lidar com chamadas ao sistema (como consultas, arquivos, sockets e etc)&lt;/li&gt;
&lt;li&gt;Enquanto o libuv trabalha, o Event Loop continua livre, processando outras requisições, timer e callbacks&lt;/li&gt;
&lt;li&gt;Quando a operação termina, o libuv notifica o Event Loop, que agenda a resolução da Promise na microtask queue&lt;/li&gt;
&lt;li&gt;O JavaScript engine retoma a execução da função extamente após o await&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ou seja, quando a operação assíncrona é disparada com o await, o JavaScript entende que devemos "pausar" a execução daquela função para esperar o resultado do que precisamos para prosseguir mas não deixa de executar outras funções por conta disso.&lt;/p&gt;

&lt;h3&gt;
  
  
  O comportamento do await
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getUsers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;antes&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;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;- pausa lógica&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;depois&lt;/span&gt;&lt;span class="dl"&gt;'&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 que acontece internamente:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O Node.js executa tudo até chegar no &lt;code&gt;await&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;O &lt;code&gt;db.findAll()&lt;/code&gt; retorna uma Promise pendente&lt;/li&gt;
&lt;li&gt;O runtime "pausa logicamente" a função &lt;code&gt;getUsers&lt;/code&gt;, guardando seu contexto (variáveis locais, escopo, posição atual)&lt;/li&gt;
&lt;li&gt;A função retorna imediatamente uma Promise pendente ao chamador&lt;/li&gt;
&lt;li&gt;Enquanto isso, o Node.js continua executando outras tarefas que aparecem no Event Loop&lt;/li&gt;
&lt;li&gt;Quando o banco responde, o callback da Promise é enfileirado na Microtask queue&lt;/li&gt;
&lt;li&gt;O Event Loop retorna a execução da função logo após o await&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Mas o que significa "pausar a função"?
&lt;/h2&gt;

&lt;p&gt;Pausar não seria bloquear a CPU e nem travar a thread principal do Node.&lt;/p&gt;

&lt;p&gt;Significa apenas que a execução daquela função em sí é suspensa de forma cooperativa até que a Promise retorne um valor para dar continuidade.&lt;/p&gt;

&lt;p&gt;Enquanto isso:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O contexto da função fica salvo&lt;/li&gt;
&lt;li&gt;O Event Loop continua processando outras tarefas&lt;/li&gt;
&lt;li&gt;A thread principal nunca fica ociosa esperando algo&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Explicação envolvendo duas funções
&lt;/h3&gt;

&lt;p&gt;Quando eu estava realmente aprendendo o papel do async/await em funções assíncronas também ficava me perguntando: é fácil visualizar o que acontece com uma função, mas quando várias funções ao mesmo tempo trabalham dessa maneira?&lt;/p&gt;

&lt;p&gt;Imagina que existam duas funções em execução simultaneamente:&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;A&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;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A terminou&lt;/span&gt;&lt;span class="dl"&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;function&lt;/span&gt; &lt;span class="nf"&gt;B&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;B executando&lt;/span&gt;&lt;span class="dl"&gt;'&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 fluxo das duas funções seria basicamente esse:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;A&lt;/code&gt; é chamado =&amp;gt; executa até o &lt;code&gt;await&lt;/code&gt; e dispara a query para o banco de dados.&lt;/li&gt;
&lt;li&gt;A query é enviada da Call Stack para a Libuv, que cuida dessa Promise no background.&lt;/li&gt;
&lt;li&gt;O Event Loop roda &lt;code&gt;B&lt;/code&gt; enquanto o banco processa a consulta da função &lt;code&gt;A&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Quando a Promise de &lt;code&gt;A&lt;/code&gt; resolve, ela é re-enfileirada.&lt;/li&gt;
&lt;li&gt;A função &lt;code&gt;A&lt;/code&gt; retoma e finaliza com &lt;code&gt;A&lt;/code&gt; resolvida.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Apenas a função &lt;code&gt;A&lt;/code&gt; "pausou", o Node.js nunca parou de executar outras coisas, e esse exemplo com apenas duas funções pode se extender a milhares de funções simultâneas&lt;/p&gt;




&lt;h3&gt;
  
  
  Papeis dos componentes explicados
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;await&lt;/code&gt;: Suspende a execução da função até a Promise resolver&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Promise&lt;/code&gt;: Representa o resultado futuro de uma operação assíncrona&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Libuv&lt;/code&gt;: Executa operações de I/O fora da thread do Event Loop&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Event Loop&lt;/code&gt;: Coordena execuções de tasks e microtasks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Microtask queue&lt;/code&gt;: Fila que contém Promises resolvidas aguardando execução da Call Stack&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Thread principal&lt;/code&gt;: Executa JavaScript, nunca bloqueada por await&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Conclusão para fixar
&lt;/h3&gt;

&lt;p&gt;O &lt;code&gt;await&lt;/code&gt; é, essencialmente, uma forma elegante de “esperar sem travar”. Ele permite que você escreva código assíncrono com aparência de código síncrono, pausando a execução apenas daquela função até que uma Promise seja resolvida — sem bloquear o restante da aplicação.&lt;/p&gt;

&lt;p&gt;Na prática, isso significa mais legibilidade e menos complexidade, evitando encadeamentos confusos de &lt;code&gt;.then()&lt;/code&gt; ao trabalhar com Promises, e passa a ter um fluxo mais linear e fácil de entender. Ao mesmo tempo, por baixo dos panos, o comportamento continua sendo assíncrono e eficiente.&lt;/p&gt;

&lt;p&gt;Em resumo, o &lt;code&gt;await&lt;/code&gt; não torna o código síncrono, ele só faz parecer que é, enquanto mantém a vantagem da execução assíncrona.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>Promises: estados, filas, encadeamento e relação com Event Loop</title>
      <dc:creator>Henrique Reis</dc:creator>
      <pubDate>Mon, 02 Feb 2026 19:55:55 +0000</pubDate>
      <link>https://dev.to/reishenrique/promises-estados-filas-encadeamento-e-relacao-com-event-loop-48lf</link>
      <guid>https://dev.to/reishenrique/promises-estados-filas-encadeamento-e-relacao-com-event-loop-48lf</guid>
      <description>&lt;p&gt;Uma Promise é um objeto que representa o resultado eventual de uma operação assíncrona, como uma chamada de API, permitindo lidar com resultados e erros de forma mais organizada do que os antigos callbacks. Usando métodos como &lt;code&gt;.then()&lt;/code&gt; para sucesso e &lt;code&gt;.catch()&lt;/code&gt; para falhas, ele funciona como um "contrato" de que um valor estará disponível agora, daqui a pouco ou nunca.&lt;/p&gt;




&lt;h2&gt;
  
  
  Estados de uma Promise
&lt;/h2&gt;

&lt;p&gt;Uma Promise pode estar em apenas &lt;strong&gt;um&lt;/strong&gt; dos três estados abaixo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;pending&lt;/code&gt; - ainda está em execução&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fulfilled&lt;/code&gt; - foi concluída com sucesso&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rejected&lt;/code&gt; - foi concluída com erro&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esses estados são imutáveis: uma vez &lt;strong&gt;fulfilled ou rejected&lt;/strong&gt;, a Promise não voltará para &lt;strong&gt;pending&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Por que Promises existem?
&lt;/h2&gt;

&lt;p&gt;Para resolver o problema do callback hell e trazer um modelo mais &lt;strong&gt;previsível, encadeável e configável&lt;/strong&gt; para operações assíncronas.&lt;/p&gt;

&lt;p&gt;Com Promises conseguimos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Evitamos pirâmides de callback&lt;/li&gt;
&lt;li&gt;Tratamos erros de forma unificada&lt;/li&gt;
&lt;li&gt;Encadeamos operações de forma mais clara&lt;/li&gt;
&lt;li&gt;Temos integrações perfeitas com &lt;code&gt;async/await&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Criando uma Promise:
&lt;/h2&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;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&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;sucesso&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&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;sucesso&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Working!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Something wrong!&lt;/span&gt;&lt;span class="dl"&gt;"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função passada para o construtor recebe dois parâmetros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;resolve(value)&lt;/code&gt; =&amp;gt; finaliza com sucesso.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;reject(value)&lt;/code&gt; =&amp;gt; finaliza com erro (o reject não espera um erro mas é uma boa prática rejeitar com um objeto Error para facilitar o debugging, stack trace e identificar falhas -- &lt;code&gt;reject(new Error('error))&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Consumindo Promises:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getOrder&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;orders&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;sendEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cada &lt;code&gt;.then()&lt;/code&gt; adiciona uma nova microtask no Event Loop (explicado mais afundo durante o estudo)&lt;/p&gt;

&lt;p&gt;Outro exemplo de encadeamento:&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// 7&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Uso do &lt;code&gt;.finally()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Executa sempre, independemente de sucesso ou erro&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="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sucesso&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;erro&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;finally&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sempre executa&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;h2&gt;
  
  
  Relação das Promises com o Event Loop
&lt;/h2&gt;

&lt;p&gt;Como já sabemos (se chegou até aqui e ainda não tiver noção básica de como o Event Loop funciona, recomendo fortemente que volte e entenda um pouco sobre antes de continuar), o Event Loop é o coração da execução assíncrona no JavaScript.&lt;/p&gt;

&lt;p&gt;Ele controla a ordem em que o código é executado e coordena todas as operações assíncronas -- inclusive Promises, é essencial entender como elas interagem entre sí.&lt;/p&gt;

&lt;h2&gt;
  
  
  O JavaScript é single-threaded, o ambiente não
&lt;/h2&gt;

&lt;p&gt;O motor JavaScript roda em uma única thread, porém o ambiente (Node.js ou navegador) possui várias APIs assíncronas (Web APIs e libuv) que operam fora dessa thread e devolvem o resultado via filas gerenciadas pelo Event Loop.&lt;/p&gt;

&lt;p&gt;Promises utilizam a &lt;strong&gt;microtask queue&lt;/strong&gt;, que tem prioridade sobre callbacks de &lt;code&gt;setTimeout&lt;/code&gt; por exemplo, que ficam na &lt;strong&gt;macrotask queue&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O ciclo do Event Loop segue esta ordem:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Executa todo o código síncrono&lt;/li&gt;
&lt;li&gt;Executa todas as microtasks pendentes&lt;/li&gt;
&lt;li&gt;Executa uma macrotask (se não tiver mais microtasks pendentes)&lt;/li&gt;
&lt;li&gt;Repete o ciclo&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Por isso que Promises são mais rápidas que timeouts:&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="nf"&gt;setTimeout&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;timeout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;microtask&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;// microtask&lt;/span&gt;
&lt;span class="c1"&gt;// timeout&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Mas quando uma Promise é resolvida, elas são tratadas como callbacks?
&lt;/h2&gt;

&lt;p&gt;Conceitualmente, sim mas uma diferença fundamental&lt;/p&gt;

&lt;p&gt;Quando uma Promise é resolvida ou rejeitada, o callback associado a ela não executa imediatamente, ele é agendado na microtask queue, como dito anteriormente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Promise.resolve(10).then(x =&amp;gt; console.log(x));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A execução inicial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a chamada &lt;code&gt;Promise.resolve(10)&lt;/code&gt; é executada na Call Stack&lt;/li&gt;
&lt;li&gt;a Promise é criada e já nasce no estado &lt;code&gt;fulfilled&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;a chamada &lt;code&gt;.then()&lt;/code&gt; também é executada na Call Stack&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O &lt;code&gt;.then()&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;não executa o callback&lt;/li&gt;
&lt;li&gt;apenas registra um &lt;strong&gt;Promise Reaction Record&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;esse reaction é armazenado internamente pelo motor JS&lt;/li&gt;
&lt;li&gt;nada é enfileirado ainda&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quando a Promise é &lt;code&gt;fulfilled&lt;/code&gt; ou &lt;code&gt;rejected&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;o motor JS percorre os &lt;strong&gt;Promise Reaction Records&lt;/strong&gt; registrados&lt;/li&gt;
&lt;li&gt;para cada reaction, cria um &lt;strong&gt;Promise Reaction Job&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;esse job contém o callback registrado no &lt;strong&gt;then/catch/finally&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;o motor JS agenda internamente esse job como uma microtask&lt;/li&gt;
&lt;li&gt;a microtask é colocada na &lt;strong&gt;microtask queue&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ou seja, o que realmente acontece é que o motor JavaScript percorre a lista de Promise Reaction Records e, para cada um deles, cria um PromiseReactionJob. Esse job é então agendado na microtask queue. É dentro desse reaction job que o callback registrado no then, catch ou finally é efetivamente executado.&lt;/p&gt;

&lt;p&gt;Modelo mental do que acontece, para ter uma visualização do fluxo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.then()
  ↓
cria um Promise Reaction Record (armazena o callback)
  ↓
quando a Promise resolve/reject
  ↓
o motor JS cria um PromiseReactionJob para cada Promise Reaction Record registrado
  ↓
job onde o callback está registrado (then/catch/finally)
  ↓
agenda o job na Microtask Queue
  ↓
executa na Call Stack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  O ponto que muda tudo
&lt;/h2&gt;

&lt;p&gt;No caso das Promises, todo o fluxo acontece inteiramente dentro do motor JavaScript. Não há envolvimento de Web APIs, libuv ou eventos externos. O agendamento ocorre por meio do job scheduling interno do próprio engine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Por isso, no funcionamento do Event Loop, os callbacks enfileirados como microtasks sempre têm prioridade sobre os enfileirados como macrotasks.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Como as Promises são resolvidas internamente pelo motor JavaScript, seus reaction jobs são agendados como microtasks e, por esse motivo, são sempre executados antes de qualquer macrotask.&lt;/p&gt;




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

&lt;p&gt;Ao longo deste estudo, vimos que Promises vão muito além de uma simples alternativa a callbacks. Elas introduzem um modelo interno de execução assíncrona que é tratado diretamente pelo motor JavaScript, sem depender de ambiente externo.&lt;/p&gt;

&lt;p&gt;Entender que:&lt;br&gt;
&lt;code&gt;.then()&lt;/code&gt;, &lt;code&gt;.catch()&lt;/code&gt; e &lt;code&gt;.finally()&lt;/code&gt; não executam callbacks imediatamente, mas registram Promise Reaction Records, que posteriormente geram PromiseReactionJobs nos quais são agendados como microtasks, é o ponto que realmente muda a forma como enxergamos o Event Loop.&lt;/p&gt;

&lt;p&gt;Justamente esse mecanismo interno que explica por que Promises são previsíveis, se encadeiam de forma segura e sempre têm prioridade sobre macrotasks, como setTimeout, mesmo com delay zero.&lt;/p&gt;

&lt;p&gt;Quando conseguimos entender esse fluxo, muitos "comportamentos estranhos" que nos deparamos durante o dia a dia no desenvolvendo em JavaScript ou TypeScript, deixam de ser mágicos e passam a fazer mais sentido. Promises não são mais uma caixa-preta -- &lt;strong&gt;elas são apenas jobs bem organizados, executados no momento certo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Se você quiser avançar ainda mais, o próximo passo natural seria entender como podemos realizar tratativas de erros, como os métodos especiais como Promise.all, Promise.allSettled e Promise.race funcionam e também como o async/await se apoia exatamente nesse mesmo mecanismo, apenas oferecendo uma sintaxe mais legível sobre as Promises que já conhecemos.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Stack memory e Heap memory</title>
      <dc:creator>Henrique Reis</dc:creator>
      <pubDate>Wed, 15 Oct 2025 22:36:54 +0000</pubDate>
      <link>https://dev.to/reishenrique/stack-memory-vs-heap-memory-183n</link>
      <guid>https://dev.to/reishenrique/stack-memory-vs-heap-memory-183n</guid>
      <description>&lt;p&gt;Embora esses dois tipos de memórias se refiram a formas diferentes de alocar e gerenciar dados durante a execução de um programa, entender como funcionam ajuda a prever o desempenho e possíveis comportamentos inesperados do código em desenvolvimento.&lt;/p&gt;

&lt;p&gt;O compilador tem acesso direto à &lt;strong&gt;stack memory&lt;/strong&gt;, já que ela é usada para armazenar variáveis locais e dados cujo o tamanho é conhecido em tempo de compilação (significa que o compilador sabe exatamente quantos bytes aquele dado vai ocupar antes do programa começar a rodar, ou seja, o tamanho da variável é fixa e previsível), o que garante maior eficiência.&lt;/p&gt;

&lt;p&gt;Por outro lado, a &lt;strong&gt;heap memory&lt;/strong&gt; é utilizada para armazenar dados que precisam permanecer acessíveis além do escopo atual ou cujo o tamanho só é conhecido em tempo de execução. Nela ficam os valores "reais" apontados por variáveis de referência, como objetos, arrays e estruturas dinâmicas.&lt;/p&gt;




&lt;h3&gt;
  
  
  Stack Memory
&lt;/h3&gt;

&lt;p&gt;A stack memory é responsável por armazenar tipos por valor. Mas o que são tipos por valor?&lt;/p&gt;

&lt;p&gt;Tipos por valor são aqueles em que a variável &lt;strong&gt;guarda diretamente o valor em si&lt;/strong&gt;, e não uma referência para ele.&lt;/p&gt;

&lt;p&gt;Exemplos comuns de tipos por valor: &lt;code&gt;number&lt;/code&gt;, &lt;code&gt;boolean&lt;/code&gt;, &lt;code&gt;char&lt;/code&gt;, &lt;code&gt;struct&lt;/code&gt;, &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;float&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;let&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;10&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;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 10 =&amp;gt; não foi afetado&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mas stack memory, também é uma estrutura de dados LIFO (Last in, First out), onde armazena dados de curta duração, como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chamadas de funções (frames da stack)&lt;/li&gt;
&lt;li&gt;Variáveis primitivas (valores por valor, como mencionado anteriormente)&lt;/li&gt;
&lt;li&gt;Referências para objetos que estão na heap&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Algumas características são:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Rápida, alocação e desalocação ocorrem automaticamente, ajustando apenas o stack pointer.&lt;/li&gt;
&lt;li&gt;Limitada, espaço pequeno (em torno de ~1MB por thread no Node.js por exemplo, podendo variar por sistema).&lt;/li&gt;
&lt;li&gt;Limpeza automática quando uma função termina (os frames são removidos da pilha).&lt;/li&gt;
&lt;li&gt;Armazena variáveis locais, parâmetros de função e endereços de retorno.&lt;/li&gt;
&lt;li&gt;Quando a pilha antige seu limite, ocorre o erro conhecido como &lt;strong&gt;"stack overflow"&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Heap Memory
&lt;/h3&gt;

&lt;p&gt;Já a heap memory é responsável por armazenar tipos por referência.&lt;/p&gt;

&lt;p&gt;Tipos por referência são aqueles em que a variável guarda o endereço (referência) do valor na memória, &lt;strong&gt;e não o valor em sí.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Quando uma variável é copiada, ambas passam a &lt;strong&gt;apontar para o mesmo dado&lt;/strong&gt;, e alterar uma afeta a outra.&lt;/p&gt;

&lt;p&gt;Tipos dos dados mais comuns utilizados por referência são: &lt;code&gt;object&lt;/code&gt;, &lt;code&gt;array&lt;/code&gt;, &lt;code&gt;function&lt;/code&gt;(em JS), classes ou ponteiros.&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;let&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;x&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;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&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="c1"&gt;// 20 =&amp;gt; ambos apontam para o mesmo objeto&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A heap é uma região da memória usada para armazenar dados dinâmicos, cujo o tamanho ou tempo de vida não são conhecidos em tempo de compilação. Nela ficam os valores reais referenciados pelas variáveis da stack.&lt;/p&gt;

&lt;p&gt;Algumas características:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Armazena objetos, arrays e funções.&lt;/li&gt;
&lt;li&gt;Permite alocação dinâmica de memória.&lt;/li&gt;
&lt;li&gt;É mais lenta que a stack, pois envolve gerenciamento de memória e ponteiros.&lt;/li&gt;
&lt;li&gt;É gerenciada automaticamente por um Garbage Collector (em linguagens como JavaScript, Java, Go)&lt;/li&gt;
&lt;li&gt;Os dados permanecem na memória até não serem mais referenciados.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  E quando um dado deixa de ser referencido?
&lt;/h3&gt;

&lt;p&gt;Um dado (&lt;code&gt;objeto&lt;/code&gt;, &lt;code&gt;array&lt;/code&gt; ou &lt;code&gt;função&lt;/code&gt;) deixa de ser referenciado quando nenhuma variável ou estrutura ativa do programa aponta mais para ele na memória.&lt;/p&gt;

&lt;p&gt;Em outras palavras: não existe mais nenhum caminho, a partir do código em execução, que leve até aquele valor na heap.&lt;/p&gt;

&lt;p&gt;Quando isso acontece, o garbage collector entende que o valor &lt;strong&gt;não pode mais ser acessado e libera a memória automaticamente&lt;/strong&gt;, um exemplo bem básico:&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;let&lt;/span&gt; &lt;span class="nx"&gt;user&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;John&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// A variável user referencia o objeto na heap&lt;/span&gt;

&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;span class="c1"&gt;// Agora não existe mais nenhuma referência para o objeto { name: 'John' }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O objeto { name: 'John' } ainda existe fisicamente na heap mas como &lt;strong&gt;nenhuma variável aponta para ele&lt;/strong&gt;, o garbage collector irá removê-lo em algum momento. Agora um outro exemplo interessante de perda de 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;let&lt;/span&gt; &lt;span class="nx"&gt;obj1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;x&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;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;obj2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;obj1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;obj1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="c1"&gt;// Ainda há uma referência ativa (obj2), então o dado continua na heap&lt;/span&gt;

&lt;span class="nx"&gt;obj2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="c1"&gt;// Agora não há mais nenhuma — o dado é elegível para coleta&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Stack + Heap em conjunto (para assimilar mais rápido)
&lt;/h3&gt;

&lt;p&gt;Durante a execução de um programa, a stack e a heap trabalham lado a lado par armazenar e gerenciar dados de forma eficiente.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;stack&lt;/strong&gt; guarda as &lt;strong&gt;referências&lt;/strong&gt; e &lt;strong&gt;valores simples (por valor)&lt;/strong&gt;, enquanto a &lt;strong&gt;heap&lt;/strong&gt; armazena os &lt;strong&gt;valores complexos (por referência)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Quando uma variável na stack aponta para um objeto ou array, o &lt;strong&gt;endereço de memória desse objeto&lt;/strong&gt; fica salvo na stack, mas o conteúdo real está na heap (como foi explicado anteriormente), 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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createUser&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;user&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="s2"&gt;Henrique&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&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;user&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;newUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;A função &lt;code&gt;createUser&lt;/code&gt; cria uma variável user na &lt;strong&gt;stack&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Essa variável &lt;strong&gt;guarda uma referência&lt;/strong&gt; para um objeto armazenado na heap.&lt;/li&gt;
&lt;li&gt;Quando a função termina, a stack é liberada, mas o objeto na heap &lt;strong&gt;permanece&lt;/strong&gt; se ainda estiver sendo referenciado (&lt;code&gt;newUser&lt;/code&gt; aponta para ele por exemplo).&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Blank Space
&lt;/h3&gt;

&lt;p&gt;Blank space é um espaço entre a stack memory e a heap memory, que é utilizada para expansão de uma das memórias caso haja necessidade (é interessante saber que existe caso queiram se aprofundar mais sobre o assunto).&lt;/p&gt;




&lt;p&gt;Espero que esta explicação tenha ajudado a entender de forma prática o papel da stack e da heap, e como eles impactam a performance e o funcionamento do código. Ainda há muito a explorar sobre esse tema, como o funcionamento do Garbage Collector, otimizações de memória e outros detalhes que merecem posts e estudos dedicados da minha parte. Para quem quiser se aprofundar, certamente vale a pena.&lt;/p&gt;

</description>
      <category>computerscience</category>
      <category>performance</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>Guards vs Interceptors no NestJS: quando usar cada um?</title>
      <dc:creator>Henrique Reis</dc:creator>
      <pubDate>Fri, 18 Apr 2025 01:04:05 +0000</pubDate>
      <link>https://dev.to/reishenrique/guards-vs-interceptors-no-nestjs-quando-usar-cada-um-2moj</link>
      <guid>https://dev.to/reishenrique/guards-vs-interceptors-no-nestjs-quando-usar-cada-um-2moj</guid>
      <description>&lt;p&gt;Recentemente tenho me aprofundado nas ferramentas que o NestJS proporciona por conta de projetos que trabalho atualmente, hoje gostaria de trazer um pouco sobre os &lt;strong&gt;Guards&lt;/strong&gt; e &lt;strong&gt;Interceptors&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;No Nest, tanto &lt;strong&gt;Guards&lt;/strong&gt; quanto &lt;strong&gt;Interceptors&lt;/strong&gt; são ferramentas poderosas do ciclo de vida das requisições. Mas cada um tem seu papel, e entender quando usar um ou outro pode te ajudar a escrever código mais limpo, seguro e organizado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Guards
&lt;/h2&gt;

&lt;p&gt;São classes que implementam a interface &lt;strong&gt;CanActivate&lt;/strong&gt; e são responsáveis por &lt;strong&gt;determinar se uma rota pode ou não ser acessada.&lt;/strong&gt; Eles são executados antes do controllers e até antes dos interceptors também.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O que é possível fazer com Guards?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verificar se o usuário está autenticado (JWT, Keycloak, etc)&lt;/li&gt;
&lt;li&gt;Autorização por roles (admin, user, departamentos)&lt;/li&gt;
&lt;li&gt;Verificação de escopos de permissões&lt;/li&gt;
&lt;li&gt;Feature toggles (acesso a funcionalidades baseado em planos de executação)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Exemplo:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RolesGuard&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;CanActivate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;requiredRole&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="c1"&gt;// Recebe a role necessária no construtor&lt;/span&gt;

 &lt;span class="nf"&gt;canActivate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ExecutionContext&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&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;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;switchToHttp&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getRequest&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="c1"&gt;// Assume que o user já foi validado&lt;/span&gt;

  &lt;span class="c1"&gt;// Verifica se o usuer tem a role necessaria para processeguir&lt;/span&gt;
  &lt;span class="k"&gt;return&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;roles&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;requiredRole&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Aplicando o Guard no Controller&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;UseGuard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;RolesGuard&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&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;protected&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;getProtectEndpoint&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Só é acessado se passar pelo Guard&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;&lt;strong&gt;Ou Globalmente&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useGlobalGuards&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RolesGuard&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Algumas vantagens&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rápidos e diretos, impedem que lógica do controller seja executada desnecessariamente.&lt;/li&gt;
&lt;li&gt;Centralizam regras de acesso&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tradeoff&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Não são ideias para transformar dados ou tratar respostas.&lt;/li&gt;
&lt;li&gt;Devem retornar apenas &lt;code&gt;true&lt;/code&gt; ou &lt;code&gt;false&lt;/code&gt; (ou &lt;code&gt;throw&lt;/code&gt; se for necessário lançar alguma exceção)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Interceptors
&lt;/h2&gt;

&lt;p&gt;No NestJS é um decorator (&lt;code&gt;@UseInterceptors()&lt;/code&gt;) que permite você aplicar interceptadores em controladores ou métodos de rota. Esses interceptadores é uma poderosa ferramente que permite &lt;strong&gt;interceptar, transformar, monitorar ou até substituir o comportamento padrão de requisições e respostas&lt;/strong&gt;. Eles são como "middlewares inteligentes" que o NestJS proporciona.&lt;/p&gt;

&lt;p&gt;O &lt;code&gt;@UseInterceptors()&lt;/code&gt; permite executar lógica antes ou depois da execução de um handler (como um método de rota, por exemplo).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Como eles funcionam?&lt;/strong&gt;&lt;br&gt;
Quando aplicado a um método ou controller, o interceptor intercepta o ciclo de vida da requisição e te dá a chance de:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modificar os dados da requisição antes de chegar no handler&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modificar ou formatar a resposta antes dela ser enviada de volta ao cliente (ou front-end)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Medir tempo de execução&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adicionar lógica comum como logging, cache, autenticação e etc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Exemplo bem genérico:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;UseInterceptors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MyInterceptor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&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;data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;getData&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;World&lt;/span&gt;&lt;span class="dl"&gt;'&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;Nest exemplo, a classe &lt;code&gt;MyInterceptor&lt;/code&gt; vai ser executada antes e/ou depois do método &lt;code&gt;getData()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Um Interceptor básico&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoggingIntercetor&lt;/span&gt; &lt;span class="nx"&gt;implement&lt;/span&gt; &lt;span class="nx"&gt;NestInterceptor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nf"&gt;intercept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ExecutionContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CallHandler&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Antes da execução do handler&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;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&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;next&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="nf"&gt;tap&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Depois... &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;ms`&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse Interceptor apenas loga o tempo que o método levou para responder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tradeoff&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Podem ser complexos se usados em excesso, o aninhamento de vários interceptadores pode não ser uma boa escolha e é passível de se adotar uma outra estratégia.&lt;/li&gt;
&lt;li&gt;Lógica errada pode afetar todos os endpoints sem perceber.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;O uso de &lt;strong&gt;Guards&lt;/strong&gt; ou &lt;strong&gt;Interceptors&lt;/strong&gt; é situacional, não existe certo ou errado, e sim o que seu projeto e sua aplicação demanda.&lt;/p&gt;

&lt;p&gt;Mas ultimamente estou analisando os cenários dessa forma:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;Guards&lt;/strong&gt; para decidir se a requisição continua.&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;Interceptors&lt;/strong&gt; para transformar o que acontece durante ou depois da execução.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Espero que tenha ficado claro e fácil de se entender o que cada ferramenta é capaz de fazer. Usado com parcimônia pode ser um grande aliado na hora do seu desenvolvimento!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>security</category>
    </item>
    <item>
      <title>Autenticação e Autorização</title>
      <dc:creator>Henrique Reis</dc:creator>
      <pubDate>Tue, 01 Apr 2025 21:58:12 +0000</pubDate>
      <link>https://dev.to/reishenrique/autenticacao-e-autorizacao-1nkl</link>
      <guid>https://dev.to/reishenrique/autenticacao-e-autorizacao-1nkl</guid>
      <description>&lt;h2&gt;
  
  
  Autenticação vs. Autorização
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Na construção de qualquer software, os dois termos são bastante citados durante todo o processo de desenvolvimento. É com o uso destas duas técnicas que garantimos uma maior segurança aos recursos protegidos de um sistema. Sendo assim, vou explicar um pouco do que é e como funcionam cada um deles.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Autenticação&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A autenticação é o processo de verificação da identidade digital de um usuário. Em termos simples, é qunado o usuário prova quem realmente é.&lt;/p&gt;

&lt;p&gt;Um exemplo bem comum de autenticação é a combinação &lt;code&gt;username&lt;/code&gt; e &lt;code&gt;password&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Sempre que um usuário realiza login em um sistema que exige credenciais, ele está passando por um processo de autenticação. No entanto, esse não é o único método disponível para autenticr um usuário, existem outras formas que incluem:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Validação por token
- CPF e senha
- E-mail e senha
- Certificado digital, entre outros
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Cada método de autenticação tem sua aplicação específica e pode ser combinado com outras técnicas, como autenticação multifator (MFA), para reforçar a segurança.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Autorização&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Por sua vez, a autorização é o processo que ocorre após ser validada a autenticação. Diz respeito aos privilégios que são concedidos a determinado usuário ao utilizar uma aplicação.&lt;/p&gt;

&lt;p&gt;Serve para verificar se determinado usuário terá a permissão para utilizar, executar recursos ou manipular determinadas ações, que é de fundamental importância dentro de uma aplicação.&lt;/p&gt;

&lt;p&gt;Um exemplo que posso atribuir a autorização é o uso de um ERP de uma determinada empresa, que após realizar a autenticação no sistema, o usuário do financeiro terá acesso apenas aos módulos correspondentes à realização de seu trabalho, como contas a pagar, contas a receber e etc.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Controle de acesso:
    - Usuário: John Doe
    - Setor: Financeiro

- Ações autorizadas ao usuário do setor Financeiro:
    - Contas a pagar [X]
    - Contas a receber [X]
    - Controle de estoque
    - Cadastro de usuários
    - Vendas
    - Pedidos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Já um funcionário do setor de Recursos Humanos (RH) teria acesso a módulos específicos para suas funções, como cadastro de funcionários, histórico de salários e benefícios, e controle de exames médicos.&lt;/p&gt;

&lt;p&gt;A autorização é um mecanismo fundamental para garantir que cada usuário tenha acesso apenas às informações e funcionalidades necessárias para sua função, evitando exposição indevida e desnecessária de dados muitas vezes sensíveis e ações não autorizadas.&lt;/p&gt;




&lt;p&gt;Para concluir, embora estejam diretamente relacionadas, &lt;strong&gt;autenticação e autorização&lt;/strong&gt; são processos distintos e complementares. A autenticação garante que o usuário é quem diz ser, enquanto a autorização define o que ele pode fazer dentro do sistema.&lt;/p&gt;

&lt;p&gt;Compreender e implementar corretamente esses dois conceitos é essencial para fortalecer a segurança das aplicações e proteger dados críticos contra acessos não autorizados.&lt;/p&gt;

</description>
      <category>api</category>
      <category>security</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Padrão de teste: System Under Test (SUT)</title>
      <dc:creator>Henrique Reis</dc:creator>
      <pubDate>Mon, 27 Jan 2025 19:34:10 +0000</pubDate>
      <link>https://dev.to/reishenrique/padrao-de-teste-system-under-test-sut-2i6o</link>
      <guid>https://dev.to/reishenrique/padrao-de-teste-system-under-test-sut-2i6o</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;O conceito &lt;strong&gt;System Under Test (SUT)&lt;/strong&gt; refere-se ao sistema, módulo, função ou unidade de código que está sendo testado em uma bateria de testes unitários. Ele é o foco principal do teste, ou seja, é o "objeto" que você está avaliando para garantir que seu comportamento esteja de acordo com as expectativas definidas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Características do SUT&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Foco central do teste: O SUT é o componente específico que está sendo analisado para validar sua funcionalidade.&lt;/li&gt;
&lt;li&gt;Isolamento: Em testes unitários, o SUT geralmente é isolado de dependências externas, como bancos de dados, APIs ou outros serviços, usando ferramentas como mocks, stubs ou fakes.&lt;/li&gt;
&lt;li&gt;Entrada e saída bem definidas: Um teste unitário para um SUT verifica se a saída ou comportamento está correto dado um conjunto de entradas.&lt;/li&gt;
&lt;li&gt;Pequena escala: O SUT deve ser pequeno e autocontido. Em vez de testar um sistema completo, o foco está em partes específicas, como funções, métodos ou classes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Exemplo prático&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine que você tem uma função em um sistema de gerenciamento de clínicas chamada &lt;em&gt;calculateClinicRevenue&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;calculateClinicRevenue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;appointments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Appointment&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="kr"&gt;number&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;appointments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;appt&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;total&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;appt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&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;Neste caso:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O SUT é a função &lt;em&gt;calculateClinicRevenue&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Os dados de entrada (um array de objetos &lt;em&gt;Appointment&lt;/em&gt;) e a saida (um número representando a receita total) são os alvos do teste.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Teste unitário&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;calculateClinicRevenue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&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="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should calculate the total revenue correctly&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &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;appointments&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="na"&gt;id&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="na"&gt;fee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;calculateClinicRevenue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;appointments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;appointments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledTimes&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="p"&gt;})&lt;/span&gt;

    &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should return 0 for an empty array&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &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="na"&gt;appointments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Appointment&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;calculateClinicRevenue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;appointments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;appointments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledTimes&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="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;Aqui, a função &lt;em&gt;calculateClinicRevenue&lt;/em&gt; é testada em diferentes cenários, verificando se produz a saída esperada com base nas entradas fornecidas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Boas práticas ao testar utilizando SUT&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Testar um comportamento específico por vez: Cada teste deve focar em um único aspecto do SUT para facilitar a depuração e o entendimento.&lt;/li&gt;
&lt;li&gt;Mockar dependências externas: Se o SUT possui dependências, como chamadas a APIs ou banco de dados, use mocks ou stubs para isolar o teste (mock repositories com métodos de inserção e deleção de elementos em arrays são comumente utilizados).&lt;/li&gt;
&lt;li&gt;Cobrir casos externos: Certifique-se de testar cenários normais, casos de erro e situações limite.&lt;/li&gt;
&lt;li&gt;Esclarecer o escopo do SUT: Seja claro sobre o que está sendo testado e como o SUT interage com outras partes do sistema.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Lembre-se: Ajuste este modelo de teste de acordo com a sua necessidade na aplicação. Também é possível criar funções para seu SUT, como por exemplo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;makeSut&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;sut&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CreateUser&lt;/span&gt;
    &lt;span class="nx"&gt;mockUserRepository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IUserRepository&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;mockUserRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;UserRepositoryInMemory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;users&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;sut&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CreateUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mockUserRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spyOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mockUserRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;findUserByCpf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spyOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mockUserRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;findUserById&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spyOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mockUserRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;createUser&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;sut&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mockUserRepository&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;Desta maneira é possível utilizar execute do meu SUT diretamente no meu teste, como por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const result = await sut.execute(mockUserPayload)&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resumo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O SUT é o componente principal testado em um cenário de teste unitário. Ele é isolado e avaliado com entradas e saídas controladas, garantindo que o comportamento seja validado sem interferências externas. Esse modelo de testes ajuda a identificar problemas em partes individuais do sistema de forma eficiente e granular.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>express</category>
      <category>mongodb</category>
      <category>test</category>
    </item>
    <item>
      <title>Cache: Otimizando Desempenho e Reduzindo Custos na sua aplicação</title>
      <dc:creator>Henrique Reis</dc:creator>
      <pubDate>Thu, 23 Jan 2025 00:18:38 +0000</pubDate>
      <link>https://dev.to/reishenrique/cache-otimizando-desempenho-e-reduzindo-custos-na-sua-aplicacao-458o</link>
      <guid>https://dev.to/reishenrique/cache-otimizando-desempenho-e-reduzindo-custos-na-sua-aplicacao-458o</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;O cache é uma técnica amplamente utilizada no desenvolvimento de software para melhorar o desempenho e a eficiência de sistemas. Ele se refere ao armazenamento temporário de dados frequentemente acessados ou computados para reduzir o tempo de acesso e o custo computacional de obter essas informações diretamente de uma fonte mais lenta (como um banco de dados, sistemas remoto ou disco rígido).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;O que é Cache?&lt;/strong&gt;&lt;br&gt;
Cache é uma camada intermediária de armazenamento de dados, geralmente implementada para melhorar velocidade de leitura e escrita de informações. Ele pode ser localizado:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No cliente (por exemplo, no navegador para cache de páginas web ou assets estáticos como CSS e JavaScript).&lt;/li&gt;
&lt;li&gt;No servidor (como sistemas de cache em memória, como Redis ou Memcached).&lt;/li&gt;
&lt;li&gt;Entre serviços (em proxy reversso, como o Varnish, para armazenar respostas HTTP).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tipos de Cache&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Cache em Memória:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Armazena dados na memória volátil (RAM) para acesso rápido.&lt;/li&gt;
&lt;li&gt;Exemplos: Redis, Memcached.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Cache de Disco:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Salva dados em armazenamentos secundários, como SSDs ou HDs.&lt;/li&gt;
&lt;li&gt;Exemplo: Sistema de arquivos do SO (Linux Page Cache).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Cache de página:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Armazena páginas renderizadas (HTML) para acelerar a entrega do conteúdo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Cache de Objetos:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Salva objetos ou trechos de dados, como resultados de consultas de banco de dados, otimizando buscas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Cache Distribuído:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implementado em sistemas distribuídos para compartilhar o cache entre várias instâncias.&lt;/li&gt;
&lt;li&gt;Exemplos: Amazon ElastiCache e Google Cloud Memorystore.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Cache HTTP:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Utilizado para armazenar respostas de servidores HTTP.&lt;/li&gt;
&lt;li&gt;Exemplos: Cabeçalhos HTTP ou Cache-Control e ETAG.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Como o Cache funciona?&lt;/strong&gt;&lt;br&gt;
O cache trabalha com um conceito bem conhecido, o &lt;strong&gt;chave-valor&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Um valor (o dado armazenado) é acessado ou armazenado por meio de uma chave (normalmente um identificar único, como uma URL ou ID de consulta.&lt;br&gt;
Quando um dado é requisitado:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O sistema verifica se ele está presente no cache (cache hit)&lt;/li&gt;
&lt;li&gt;Caso contrário, o dado é buscado na fonte original (cache miss), processando e armazenando no cache para acessos futuros.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Importância do Cache no System Design de aplicações&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Aceleração de desempenho&lt;/em&gt;&lt;br&gt;
O cache reduz significativamente o tempo necessário para acessar dados frequentemente requisitados, já que evita operações custosas (como consultas a banco de dados ou chamadas de APIs externas)&lt;br&gt;
Ideal para operações que envolvem leitura intensiva.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Redução de custos&lt;/em&gt;&lt;br&gt;
Menor utilização de recursos computacionais (CPU, disco e de rede).&lt;br&gt;
Reduz a carga no banco de dados e em outros sistemas críticos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Escalabilidade&lt;/em&gt;&lt;br&gt;
O cache ajuda sistemas a lidar com grande volumes de tráfegos, armazenando resultados de forma temporária para servir múltiplos usuários sem sobrecarregar o backend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Tolerância a falhas&lt;/em&gt;&lt;br&gt;
Em caso de falha em sistema downstream (como bancos de dados ou APIs externas), os dados armazenados no cache podem garantir a continuidade da aplicação temporariamente, disponibilizando informações armazenadas anteriormente.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Melhora na experiência do usuário (UX)&lt;/em&gt;&lt;br&gt;
Respostas mais rápidas a consultas ou navegação aumentam a satisfação do usuário final.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Estratégias de Cache&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Políticas de Expiração:&lt;/em&gt; Define por quanto tempo um item deve permanecer no cache. Exemplos: TTL (Time-To-Live), LRU (Least Recently Used).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Invalidações do Cache:&lt;/em&gt; Define como e quando os dados no cache devem ser atualizados ou removidos. Invalidação manual, baseada em eventos (por exemplo, uma atualização no banco de dados), TTL automático.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cache Local x Global:&lt;/em&gt; &lt;strong&gt;Local&lt;/strong&gt;: Armazena dados próximos ao consumidor (ex.: Cache no navegador), &lt;strong&gt;Global&lt;/strong&gt;: Compartilhado entre vários serviços ou instâncias (ex.: Redis)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Desafios do Cache&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Cache Miss: Quando um dado solicitado não está no cache, é necessário buscá-lo na fonte original, causando uma possível lentidão.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Problemas de consistência: Dados desatualizados no cache podem causar descreprâncias entre o sistema e a fonte original.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Supercarga de Memória: Armazenar dados excessivamente no cache pode esgotar a memória, especialmente um sistema de alto tráfego.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Invalidações complexas: Garantir que o cache seja atualizado de forma correta e no momento certo pode ser desafiador.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Soluções distribuídas: Em sistemas com múltiplos nós, manter a consistência e sincronização no cache é mais difícil.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Agora alguns exemplos onde o Cache é utilizado com frequência em aplicações reais:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;E-commerce
Armazenando produtos mais visualizados.
Cache de sessões de usuários para manter carrinhos de compra.&lt;/li&gt;
&lt;li&gt;Streaming de vídeo
Utilização de CDNs (Content Delivery Network) para armazenar vídeos perto da localização do usuário.&lt;/li&gt;
&lt;li&gt;Sistemas bancários
Cache de transações ou dados no cliente para evitar consultas constantes ao banco de dados&lt;/li&gt;
&lt;li&gt;Aplicações SaaS
Cache de configurações personalizadas do cliente para evitar latências em APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Problemas que o Cache resolve em empresas de software&lt;/strong&gt;&lt;br&gt;
Reduzir tempo de reposta: Um banco de dados com milhões de registros&lt;/p&gt;

&lt;p&gt;Redução de Custos de Infraestrutura: Com menos acesso ao banco de dados ou APIs de terceiros,  há economia de recursos e custos.&lt;/p&gt;

&lt;p&gt;Prevenção de Sobrecarga: Sistemas de alta demanda, como Black Friday em e-commerces, conseguem lidar com tráfego intenso usando cache para respostas rápidas ao clientes.&lt;/p&gt;

&lt;p&gt;Melhor Escalabilidade: Permite que um sistema suporte um número maior de usuários sem a necessidade de dimensionar excessivamente a infraestrutura.&lt;/p&gt;

&lt;p&gt;Resiliência contra Falhas: Sistemas que dependem de APIs externas podem armazenar dados no cache e operar parcialmente mesmo quando as APIs estão fora do ar.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusão&lt;/strong&gt;&lt;br&gt;
O cache é essencial no system design de aplicações modernas. Ele otimiza o desempenho, melhora a experiência do usuário e reduz custos. No entanto, o uso eficaz de cache exige planejamento cuidadoso para evitar problemas de consistência e garantir que o sistema seja escalável e resiliente. Para empresas de software, o cache é uma ferramenta indispensável para resolver desafios relacionados a desempenho.&lt;/p&gt;

</description>
      <category>redis</category>
      <category>cache</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
