<?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: Adriano P. Araujo</title>
    <description>The latest articles on Forem by Adriano P. Araujo (@dev-araujo).</description>
    <link>https://forem.com/dev-araujo</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%2F973209%2F49718ddc-dce8-4097-bfda-e17f027017d2.jpeg</url>
      <title>Forem: Adriano P. Araujo</title>
      <link>https://forem.com/dev-araujo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dev-araujo"/>
    <language>en</language>
    <item>
      <title>HTML para Devs Backend: Ou Como Aprender que Nem Tudo é uma Div</title>
      <dc:creator>Adriano P. Araujo</dc:creator>
      <pubDate>Thu, 04 Dec 2025 12:12:43 +0000</pubDate>
      <link>https://forem.com/dev-araujo/html-para-devs-backend-ou-como-aprender-que-nem-tudo-e-uma-div-1c4k</link>
      <guid>https://forem.com/dev-araujo/html-para-devs-backend-ou-como-aprender-que-nem-tudo-e-uma-div-1c4k</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Ah, HTML? Isso é fácil. É só um monte de tags. Coloca um div aqui, um div ali, um div em cima de outro div... pronto, frontend feito."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fmqylpu6f6qas9yqghksm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fmqylpu6f6qas9yqghksm.jpg" alt="mas essa é fácil, faz outra mais difícil " width="600" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se você já ouviu (ou disse) algo assim, este artigo é para você.&lt;br&gt;
Vamos falar de umas verdades que ninguém te conta quando você sai do backend para mexer no front.&lt;/p&gt;

&lt;p&gt;Você manda bem em Go, Node.js, Python, Java. Domina bancos de dados, otimiza queries, cria APIs RESTful que escalam, lida com autenticação, criptografia e concorrência. Pode debugar um problema de &lt;em&gt;race condition&lt;/em&gt; em produção enquanto toma um café.&lt;/p&gt;

&lt;p&gt;Aí surge aquele projeto interno, aquele MVP, ou pior, a única pessoa do frontend da equipe pede demissão. Você pensa: "Tranquilo, é só HTML e CSS. Vou resolver em uma tarde."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spoiler:&lt;/strong&gt; Você vai descobrir que HTML é um dos negócios mais subestimados da programação. E não, a resposta &lt;strong&gt;nunca&lt;/strong&gt; é "mais uma &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;".&lt;/p&gt;
&lt;h2&gt;
  
  
  O meme da &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; que vira pesadelo real
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- O "estilo backend" de estruturar uma página --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"logo"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Logo&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;About&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Contact&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"post"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"post-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Meu Primeiro Post&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"post-body"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Conteúdo aqui&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"footer"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"footer-content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;© 2025&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Funciona? Tecnicamente, sim. O navegador engole qualquer coisa. Parece aceitável? Provavelmente. Mas aí você tenta usar o teclado para navegar e nada acontece. Um colega cego tenta acessar com leitor de tela e ouve uma sopa de "grupo, grupo, grupo". O Google tenta indexar seu conteúdo e não consegue distinguir o menu do artigo.&lt;/p&gt;

&lt;p&gt;Acessibilidade? &lt;strong&gt;Inexistente&lt;/strong&gt;.&lt;br&gt;
SEO? &lt;strong&gt;Comprometido&lt;/strong&gt;.&lt;br&gt;
Manutenção daqui a 6 meses? &lt;strong&gt;"Que diabos esse monte de div fazia mesmo?"&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  HTML não é sobre aparência, é sobre significado
&lt;/h2&gt;

&lt;p&gt;A mentalidade que salva vidas (ou pelo menos projetos) é esta: &lt;strong&gt;HTML é uma linguagem de marcação, não de estilização&lt;/strong&gt;. Sua função principal é comunicar &lt;em&gt;significado&lt;/em&gt; e &lt;em&gt;estrutura&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Quando você usa &lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt;, você não está só organizando visualmente. Você está passando informação crucial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Para o navegador:&lt;/strong&gt; &lt;em&gt;"Aqui começa a navegação principal, destaca isso para navegação por teclado."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Para o leitor de tela:&lt;/strong&gt; &lt;em&gt;"Este é o conteúdo principal da página, vá direto para ele."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Para o Google:&lt;/strong&gt; &lt;em&gt;"Este bloco é um artigo independente, este outro é um menu."&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- O mesmo layout, agora comunicando significado --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;header&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"logo"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Logo&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;nav&lt;/span&gt; &lt;span class="na"&gt;aria-label=&lt;/span&gt;&lt;span class="s"&gt;"Principal"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/sobre"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Sobre&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/contato"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Contato&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Meu Primeiro Post&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Conteúdo significativo aqui.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;footer&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class="ni"&gt;&amp;amp;copy;&lt;/span&gt; 2025&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Percebe a diferença? É a diferença entre um monte de tijolos soltos e uma casa com portas, janelas e cômodos identificados.&lt;/p&gt;


&lt;h2&gt;
  
  
  Os 5 elementos que você está usando errado (e como consertar)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fwcmj56rdp05v9majd6pb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fwcmj56rdp05v9majd6pb.jpg" alt="Os 5 elementos que você está usando errado " width="464" height="358"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  1. &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; vs. a tragédia do &lt;code&gt;&amp;lt;div onclick=""&amp;gt;&lt;/code&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- ❌ O clássico erro --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn"&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"submitForm()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Enviar Formulário&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- ✅ O caminho correto --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"submitForm()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Enviar Formulário&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Por quê?&lt;/strong&gt; Um &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; é, por padrão:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Focável:&lt;/strong&gt; Você chega nele pressionando &lt;code&gt;Tab&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Acionável:&lt;/strong&gt; Você o ativa com &lt;code&gt;Enter&lt;/code&gt; ou &lt;code&gt;Espaço&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Semântico:&lt;/strong&gt; Leitores de tela anunciam "botão".&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Estados nativos:&lt;/strong&gt; Tem &lt;code&gt;:hover&lt;/code&gt;, &lt;code&gt;:focus&lt;/code&gt;, &lt;code&gt;:active&lt;/code&gt; e &lt;code&gt;:disabled&lt;/code&gt; de graça.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; não é nada disso. Transformá-la em botão é como usar um parafuso como martelo: funciona até você precisar de um martelo de verdade.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. A conexão perdida: &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; e &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- ❌ O que todo mundo faz no começo --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;Email:&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"userEmail"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- ✅ A maneira que funciona para todos --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"userEmail"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Email:&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"userEmail"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;A mágica do &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt;:&lt;/strong&gt; Clicar no texto "Email:" foca automaticamente no campo. Isso é um &lt;strong&gt;superpoder&lt;/strong&gt; para usabilidade em telas touch e para pessoas com dificuldades motoras. Além disso, leitores de tela leem o &lt;em&gt;label&lt;/em&gt; quando o &lt;em&gt;input&lt;/em&gt; recebe foco, dando contexto.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt;: não é um container qualquer
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- ❌ A reinvenção da roda (com JavaScript extra) --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"formContainer"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"nome"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn"&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"enviarDados()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Cadastrar&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- ✅ Usando a ferramenta certa para o trabalho --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;onsubmit=&lt;/span&gt;&lt;span class="s"&gt;"return handleSubmit(event)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"nome"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Nome:&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"nome"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"nome"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Email:&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Cadastrar&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;O poder nativo do &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Pressionar &lt;code&gt;Enter&lt;/code&gt; em qualquer campo submete o formulário.&lt;/li&gt;
&lt;li&gt;  Validação básica (&lt;code&gt;required&lt;/code&gt;, &lt;code&gt;type="email"&lt;/code&gt;) funciona &lt;strong&gt;antes&lt;/strong&gt; do JavaScript carregar.&lt;/li&gt;
&lt;li&gt;  O estado &lt;code&gt;:invalid&lt;/code&gt; do CSS te ajuda a mostrar erros.&lt;/li&gt;
&lt;li&gt;  É o jeito universal e esperado de coletar dados.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  4. &lt;code&gt;&amp;lt;img alt=""&amp;gt;&lt;/code&gt;: o atributo mais negligenciado do mundo
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- ❌ O padrão (infeliz) --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"grafico-vendas-q1.png"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- ✅ O mínimo do profissionalismo --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"grafico-vendas-q1.png"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Gráfico de linhas mostrando crescimento de 15% nas vendas no primeiro trimestre"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;O &lt;code&gt;alt&lt;/code&gt; não é um campo opcional para "deficientes visuais". Ele é:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;O texto de fallback&lt;/strong&gt; quando a imagem não carrega.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;A descrição&lt;/strong&gt; que o Google usa para entender seu conteúdo.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;A informação&lt;/strong&gt; que um leitor de tela lê em voz alta.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Contexto&lt;/strong&gt; para qualquer pessoa em uma conexão lenta que desabilitou imagens.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Escreva como se estivesse descrevendo a imagem para alguém por telefone.&lt;/p&gt;
&lt;h3&gt;
  
  
  5. &lt;code&gt;&amp;lt;a href=""&amp;gt;&lt;/code&gt; vs. &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;: a separação das coisas
&lt;/h3&gt;

&lt;p&gt;Essa é simples, mas crucial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Use &lt;code&gt;&amp;lt;a href="/pagina"&amp;gt;&lt;/code&gt;&lt;/strong&gt; para &lt;strong&gt;navegação&lt;/strong&gt;. Leva o usuário para outro lugar (página, seção, site externo).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Use &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;&lt;/strong&gt; para &lt;strong&gt;ações&lt;/strong&gt; que acontecem na página atual (abrir modal, filtrar lista, adicionar ao carrinho).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Por quê? Um link pode ser aberto em nova aba (&lt;code&gt;Ctrl+Click&lt;/code&gt;), pode ser favoritado e tem um comportamento de navegação padrão. Um botão não. Misturar os dois é confundir o usuário e ferir princípios básicos da web.&lt;/p&gt;


&lt;h2&gt;
  
  
  Atributos que são superpoderes secretos
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;aria-*&lt;/code&gt;: o manual de instruções para leitores de tela
&lt;/h3&gt;

&lt;p&gt;Quando você &lt;em&gt;precisa&lt;/em&gt; usar uma &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; para fazer algo customizado (um botão de fechar personalizado, um widget complexo), os atributos ARIA entram em cena para consertar a semântica.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Um "X" estilizado que precisa ser um botão funcional --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn-fechar"&lt;/span&gt;
     &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;           &lt;span class="err"&gt;&amp;lt;!&lt;/span&gt;&lt;span class="na"&gt;--&lt;/span&gt; &lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="na"&gt;Eu&lt;/span&gt; &lt;span class="na"&gt;me&lt;/span&gt; &lt;span class="na"&gt;comporto&lt;/span&gt; &lt;span class="na"&gt;como&lt;/span&gt; &lt;span class="na"&gt;um&lt;/span&gt; &lt;span class="na"&gt;botão&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt; &lt;span class="na"&gt;--&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
     aria-label="Fechar modal" &lt;span class="c"&gt;&amp;lt;!-- O texto que o leitor de tela vai ler --&amp;gt;&lt;/span&gt;
     tabindex="0"            &lt;span class="c"&gt;&amp;lt;!-- "Eu posso receber foco pelo teclado" --&amp;gt;&lt;/span&gt;
     onclick="fecharModal()"&amp;gt;
    &lt;span class="ni"&gt;&amp;amp;times;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Mas sério, na maioria das vezes, só use: --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn-fechar"&lt;/span&gt; &lt;span class="na"&gt;aria-label=&lt;/span&gt;&lt;span class="s"&gt;"Fechar modal"&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"fecharModal()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="ni"&gt;&amp;amp;times;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;input type=""&lt;/code&gt;: muito mais que validação
&lt;/h3&gt;

&lt;p&gt;Cada &lt;code&gt;type&lt;/code&gt; aciona comportamentos específicos e otimiza a experiência, principalmente em dispositivos móveis.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Mostra teclado com @ em mobiles --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"tel"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;   &lt;span class="c"&gt;&amp;lt;!-- Mostra teclado numérico --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"date"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;  &lt;span class="c"&gt;&amp;lt;!-- Abre um date picker nativo --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"search"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Aparece com estilo de busca e botão de limpar --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;data-*&lt;/code&gt;: a ponte segura entre HTML e JavaScript
&lt;/h3&gt;

&lt;p&gt;É a forma padrão de embutir dados no HTML sem bagunçar classes ou IDs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"produto"&lt;/span&gt;
     &lt;span class="na"&gt;data-id=&lt;/span&gt;&lt;span class="s"&gt;"789"&lt;/span&gt;
     &lt;span class="na"&gt;data-preco=&lt;/span&gt;&lt;span class="s"&gt;"29.90"&lt;/span&gt;
     &lt;span class="na"&gt;data-categoria=&lt;/span&gt;&lt;span class="s"&gt;"eletronicos"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Fones de Ouvido
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// No seu JS, acesse de forma limpa&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;produto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.produto&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&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="c1"&gt;// "789"&lt;/span&gt;
&lt;span class="c1"&gt;// Facilita passar dados para event handlers&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  A verdade que dói
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fieukyhdj5ehdnbmx0br0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fieukyhdj5ehdnbmx0br0.jpg" alt="A verdade que dói" width="300" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTML é fácil de escrever, mas difícil de dominar.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Você pode passar uma carreira inteira escrevendo HTML "funcional" sem nunca escrever HTML &lt;em&gt;bom&lt;/em&gt;. A diferença entre um e outro não é só tecnológica, é filosófica. É a diferença entre pensar em "páginas" e pensar em "experiências"; entre pensar em "usuários" e pensar em "&lt;em&gt;pessoas&lt;/em&gt;".&lt;/p&gt;

&lt;p&gt;No backend, um endpoint mal feito afeta uma aplicação. No frontend, um HTML mal feito pode excluir uma pessoa.&lt;/p&gt;




&lt;h3&gt;
  
  
  Conclusão: Pare de tratar HTML como um detalhe
&lt;/h3&gt;

&lt;p&gt;O HTML é a fundação sobre a qual toda a web é construída. Você pode ser um arquiteto de microsserviços, um mestre dos algoritmos ou um engenheiro de foguetes, mas se o HTML da sua página é uma pilha de &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; sem significado, a experiência do usuário vai ranger na base.&lt;/p&gt;

&lt;p&gt;A próxima vez que você for tocar no frontend, lembre-se: sua missão não é fazer "aparecer na tela". Sua missão é &lt;strong&gt;construir uma interface que comunique, que incluza e que funcione para todos.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;É um trabalho mais desafiador do que parece.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bônus: Para onde ir agora ?
&lt;/h3&gt;

&lt;p&gt;Se o artigo não foi suficiente, abaixo tem algumas fontes legais para consultar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/HTML" rel="noopener noreferrer"&gt;MDN Web Docs (HTML)&lt;/a&gt;:&lt;/strong&gt; O clássico &lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;a href="https://webaim.org/" rel="noopener noreferrer"&gt;WebAIM&lt;/a&gt;:&lt;/strong&gt; O guia definitivo para acessibilidade na web. Comece pelo &lt;a href="https://webaim.org/standards/wcag/checklist" rel="noopener noreferrer"&gt;Checklist de Acessibilidade&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;a href="https://html.spec.whatwg.org/" rel="noopener noreferrer"&gt;HTML - Living Standard&lt;/a&gt;:&lt;/strong&gt; A especificação oficial. É densa, mas é a fonte da verdade quando há dúvidas profundas.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;a href="https://www.a11yproject.com/" rel="noopener noreferrer"&gt;The A11Y Project&lt;/a&gt;:&lt;/strong&gt; Recursos, artigos e patterns de acessibilidade em um formato mais digerível.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Just Build It Right.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>html</category>
      <category>backend</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Adriano P. Araujo</dc:creator>
      <pubDate>Tue, 02 Dec 2025 21:36:15 +0000</pubDate>
      <link>https://forem.com/dev-araujo/-2hhc</link>
      <guid>https://forem.com/dev-araujo/-2hhc</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/dev-araujo" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F973209%2F49718ddc-dce8-4097-bfda-e17f027017d2.jpeg" alt="dev-araujo"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/dev-araujo/seguranca-em-smart-contracts-2025-a-evolucao-dos-ataques-e-a-nova-fronteira-da-defesa-7h9" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Segurança em Smart Contracts (2025): A Evolução dos Ataques e a Nova Fronteira da Defesa&lt;/h2&gt;
      &lt;h3&gt;Adriano P. Araujo ・ Dec 2&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Segurança em Smart Contracts (2025): A Evolução dos Ataques e a Nova Fronteira da Defesa</title>
      <dc:creator>Adriano P. Araujo</dc:creator>
      <pubDate>Tue, 02 Dec 2025 13:09:59 +0000</pubDate>
      <link>https://forem.com/dev-araujo/seguranca-em-smart-contracts-2025-a-evolucao-dos-ataques-e-a-nova-fronteira-da-defesa-7h9</link>
      <guid>https://forem.com/dev-araujo/seguranca-em-smart-contracts-2025-a-evolucao-dos-ataques-e-a-nova-fronteira-da-defesa-7h9</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.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%2Fyeh43xya0q088iyuljmi.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fyeh43xya0q088iyuljmi.gif" alt="moneyyyy" width="632" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Erros em smart contracts não são mais apenas bugs de código; são portas abertas em um cofre digital, e os ladrões estão cada vez mais especializados."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Perdas de mais de &lt;strong&gt;US $3,1 bilhões&lt;/strong&gt; apenas no primeiro semestre de 2025. Deixa isso afundar.&lt;/p&gt;

&lt;p&gt;Um bug em um smart contract ainda pode custar milhões. O ataque de &lt;strong&gt;reentrância&lt;/strong&gt; no The DAO em 2016? US$50 milhões. Hoje isso seria apenas uma fração dos &lt;strong&gt;US$953,2 milhões&lt;/strong&gt; perdidos em 2024 por falhas em um único vetor: &lt;strong&gt;controle de acesso&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Mas tem mais. Os desenvolvedores agora enfrentam um novo adversário: a &lt;strong&gt;Inteligência Artificial&lt;/strong&gt;. Em 2025, agentes de IA demonstraram capacidade de encontrar e explorar vulnerabilidades de forma autônoma, extraindo milhões em simuladores antes que humanos percebessem.&lt;/p&gt;

&lt;p&gt;Bem-vindo a 2025. Vamos explorar as vulnerabilidades mais críticas e como não virar notícia ruim.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚡ A Evolução da Ameaça: Os Novos Vetores Dominantes
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fczdkj8kcwi61ie5n9bfv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fczdkj8kcwi61ie5n9bfv.jpg" alt="bug evolution" width="800" height="599"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O mapa de riscos foi reorganizado. Com base em &lt;strong&gt;149 incidentes&lt;/strong&gt; que totalizaram &lt;strong&gt;US$1,42 bilhão&lt;/strong&gt;, o OWASP publicou o Top 10 de 2025. A lista reflete ataques mais complexos e combinados.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Ranking OWASP 2025&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;O Que É&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;O Estrago&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SC01 - Controle de Acesso&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Falhas na atribuição de permissões em funções críticas (mint, ownership)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;US$953,2 milhões em 2024&lt;/strong&gt; — A principal causa de perdas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SC02 - Manipulação de Oracles&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ataques que manipulam fontes de preços externas&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;US$8,8 milhões em 2024&lt;/strong&gt; — Frequentemente combinado com Flash Loans&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SC03 - Erros de Lógica&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Bugs sutis na lógica de negócio (recompensas, taxas, empréstimos)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;US$63,8 milhões em 2024&lt;/strong&gt; — Subiu para 3º lugar&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SC05 - Reentrância&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Exploração de chamadas externas não sincronizadas&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;US$35,7 milhões em 2024&lt;/strong&gt; — Agora com variantes cross-contract&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SC07 - Flash Loans&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Empréstimos sem colateral explorados em uma transação&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;US$33,8 milhões em 2024&lt;/strong&gt; — Não é um bug, é um mecanismo explorado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SC08 - Overflow/Underflow&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Operações aritméticas que extrapolam limites&lt;/td&gt;
&lt;td&gt;Reduzido desde Solidity 0.8+, mas &lt;strong&gt;atenção a código legado&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🧠 A Nova Fronteira: IA Como Atacante (e Defensor)
&lt;/h2&gt;

&lt;p&gt;Aqui está o que mantém devs de Web3 acordados à noite:&lt;/p&gt;

&lt;p&gt;Modelos como &lt;strong&gt;Claude Opus 4.5&lt;/strong&gt; e &lt;strong&gt;GPT-5&lt;/strong&gt; desenvolveram exploits para contratos vulneráveis com &lt;strong&gt;valor potencial de US$4,6 milhões&lt;/strong&gt;. Pior: em um experimento com 2.849 contratos recentes, essas IAs encontraram &lt;strong&gt;dois "zero-days"&lt;/strong&gt; (vulnerabilidades inéditas).&lt;/p&gt;

&lt;p&gt;A IA pode vasculhar milhares de contratos automaticamente, encontrando padrões que humanos demoram semanas para perceber.&lt;/p&gt;

&lt;p&gt;Mas tem um lado bom: a mesma IA que ataca pode defender. Mais sobre isso depois.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔧 Estratégias de Defesa Modernas (2025)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fbhidifx14mf3h3q660qw.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fbhidifx14mf3h3q660qw.webp" alt="defesa" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;"Codificar e implantar" é coisa do passado. Segurança agora é um &lt;strong&gt;ciclo contínuo&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Padrão de Codificação e Ferramentas
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Use Solidity 0.8.22+&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verificações aritméticas automáticas&lt;/li&gt;
&lt;li&gt;Especifique a versão de forma fixa: &lt;code&gt;pragma solidity 0.8.22;&lt;/code&gt; (não use &lt;code&gt;^&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Garante reprodutibilidade&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Bibliotecas Blindadas&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.openzeppelin.com/contracts/" rel="noopener noreferrer"&gt;&lt;strong&gt;OpenZeppelin Contracts&lt;/strong&gt;&lt;/a&gt; — Implementações seguras de padrões ERC&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.openzeppelin.com/contracts/4.x/api/proxy#ERC1967Proxy" rel="noopener noreferrer"&gt;&lt;strong&gt;UUPS (ERC1967Proxy)&lt;/strong&gt;&lt;/a&gt; — Proxy seguro para contratos upgradeable (mais eficiente em gas)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Stack de Ferramentas 2025&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/crytic/slither" rel="noopener noreferrer"&gt;&lt;strong&gt;Slither&lt;/strong&gt;&lt;/a&gt;: Análise estática com novo motor de taint analysis&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/crytic/echidna" rel="noopener noreferrer"&gt;&lt;strong&gt;Echidna&lt;/strong&gt;&lt;/a&gt;: Fuzzing para testar invariantes em estados complexos&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/trailofbits/manticore" rel="noopener noreferrer"&gt;&lt;strong&gt;Manticore&lt;/strong&gt;&lt;/a&gt;: Análise simbólica para exploração aprofundada&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.cyfrin.io/blog/supercharge-secure-solidity-development-the-aderyn-vs-code-extension" rel="noopener noreferrer"&gt;&lt;strong&gt;Aderyn (VS Code Extension)&lt;/strong&gt;&lt;/a&gt;: Auditoria em tempo real direto no seu editor — detecta vulnerabilidades enquanto você escreve&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Integração Contínua (CI)&lt;/strong&gt;&lt;br&gt;
Crie um pipeline automático que combine essas ferramentas. Bloqueia vulnerabilidades antes de cada merge.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Padrões de Projeto Seguros
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Controle de Acesso Robusto&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nunca confie apenas em &lt;code&gt;onlyOwner&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://docs.openzeppelin.com/contracts/4.x/access-control" rel="noopener noreferrer"&gt;&lt;strong&gt;OpenZeppelin AccessControl&lt;/strong&gt;&lt;/a&gt; para RBAC (Role-Based Access Control)&lt;/li&gt;
&lt;li&gt;Proteja funções administrativas com &lt;a href="https://safe.global/" rel="noopener noreferrer"&gt;&lt;strong&gt;multisig (ex: Safe)&lt;/strong&gt;&lt;/a&gt; + &lt;a href="https://docs.openzeppelin.com/contracts/4.x/governance#timelock" rel="noopener noreferrer"&gt;&lt;strong&gt;timelocks&lt;/strong&gt;&lt;/a&gt; (mínimo 24h)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Padrão Checks-Effects-Interactions (CEI)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mais crucial que nunca&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Atenção:&lt;/strong&gt; Modificadores que fazem chamadas externas violam o CEI&lt;/li&gt;
&lt;li&gt;Use modificadores apenas para checagens simples&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Validação de Entrada Exaustiva&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Não valide apenas endereços zero&lt;/li&gt;
&lt;li&gt;Verifique se são contratos (use &lt;code&gt;extcodesize&lt;/code&gt; no constructor)&lt;/li&gt;
&lt;li&gt;Defina limites para parâmetros&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;require()&lt;/code&gt; com mensagens claras ou &lt;strong&gt;erros customizados&lt;/strong&gt; (mais barato em gas)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Auditoria e Governance Pós-Deploy
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Auditoria profissional deixou de ser luxo. É requisito mínimo.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Quase &lt;strong&gt;metade dos contratos exploráveis é atacada em até 30 dias após o deploy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auditoria Híbrida&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Revisão interna por pares em cada PR&lt;/li&gt;
&lt;li&gt;Auditorias externas trimestrais ou antes de grandes mudanças&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Monitoramento em Tempo Real&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;a href="https://docs.openzeppelin.com/defender/sentinel" rel="noopener noreferrer"&gt;&lt;strong&gt;OpenZeppelin Defender Sentinel&lt;/strong&gt;&lt;/a&gt; para alertas de eventos suspeitos&lt;/li&gt;
&lt;li&gt;Mudança de owner? Grandes saques? Você fica sabendo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Plano de Resposta a Incidentes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tenha propostas de governance de emergência pré-escritas&lt;/li&gt;
&lt;li&gt;Teste-as. Sério.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Proteção Proativa com IA&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Se IA pode atacar, também pode defender&lt;/li&gt;
&lt;li&gt;Use ferramentas de auditoria assistida por IA&lt;/li&gt;
&lt;li&gt;Faça "testes de estresse" buscando padrões que modelos ofensivos explorariam&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧪 Caso Prático: Um Contrato Vulnerável Real
&lt;/h2&gt;

&lt;p&gt;Aqui está um exemplo inspirado em vulnerabilidades reais encontradas por IA:&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Contrato Vulnerável
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract RewardToken {
    mapping(address =&amp;gt; uint256) private _balances;
    mapping(address =&amp;gt; uint256) public rewards;

    // Faltou o modificador 'view'! ⚠️
    function calculateRewards(address user) public returns (uint256) {
        uint256 reward = _balances[user] * 0.01;
        rewards[user] += reward;  // Estado modificado inadvertidamente!
        return reward;
    }

    function claimRewards() external {
        uint256 amount = rewards[msg.sender];
        require(amount &amp;gt; 0, "No rewards");
        rewards[msg.sender] = 0;
        (bool success, ) = msg.sender.call{value: amount}("");
        require(success, "Transfer failed");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ✅ Contrato Corrigido
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract RewardTokenSecure {
    mapping(address =&amp;gt; uint256) private _balances;
    mapping(address =&amp;gt; uint256) public rewards;

    // 1. Marcado como 'view' — não modifica estado
    function calculateRewards(address user) public view returns (uint256) {
        return _balances[user] * 0.01;
    }

    // 2. Nova função para ATUALIZAR recompensas, com controle de acesso
    function updateUserRewards(address user) external {
        require(msg.sender == user || hasRole(REWARD_UPDATER_ROLE, msg.sender), "Unauthorized");
        uint256 reward = calculateRewards(user);
        rewards[user] += reward;
    }

    // 3. Padrão CEI aplicado
    function claimRewards() external nonReentrant {
        // CHECK
        uint256 amount = rewards[msg.sender];
        require(amount &amp;gt; 0, "No rewards");

        // EFFECT
        rewards[msg.sender] = 0;

        // INTERACTION
        (bool success, ) = msg.sender.call{value: amount}("");
        require(success, "Transfer failed");
    }

    // 4. RBAC com OpenZeppelin
    bytes32 public constant REWARD_UPDATER_ROLE = keccak256("REWARD_UPDATER_ROLE");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📈 O Futuro: Automação, Regulação e Responsabilidade
&lt;/h2&gt;

&lt;p&gt;Com o aumento da adoção institucional, a negligência previsível em segurança está virando &lt;strong&gt;risco legal&lt;/strong&gt; para fundadores e auditores.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automação da Defesa&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fuzzing já é padrão&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auditoria contínua por IA&lt;/strong&gt; será integrada ao pipeline de desenvolvimento&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Transparência e Comunidade&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Auditoria de código aberto&lt;/li&gt;
&lt;li&gt;Bug bounties via &lt;a href="https://immunefi.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Immunefi&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Resiliência Pós-Deploy&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Capacidade de responder, pausar, atualizar (via proxies seguros)&lt;/li&gt;
&lt;li&gt;Compensar usuários em caso de incidente&lt;/li&gt;
&lt;li&gt;Tão importante quanto evitar o bug inicial&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusão: A Imutabilidade é uma Espada de Dois Gumes
&lt;/h2&gt;

&lt;p&gt;A promessa dos smart contracts — código autoexecutável e imutável — continua sendo sua maior força e seu maior perigo.&lt;/p&gt;

&lt;p&gt;A diferença entre 2016 e 2025:&lt;/p&gt;

&lt;p&gt;→ &lt;strong&gt;Mapas detalhados dos campos minados&lt;/strong&gt; (OWASP Top 10)&lt;br&gt;
→ &lt;strong&gt;Ferramentas de detecção avançadas&lt;/strong&gt; (Slither, Echidna, IA)&lt;br&gt;
→ &lt;strong&gt;Padrões de defesa comprovados&lt;/strong&gt; (CEI, AccessControl, UUPS)&lt;/p&gt;

&lt;p&gt;O desafio atual não é apenas conhecer as vulnerabilidades clássicas, mas entender como elas evoluem, se combinam em ecossistemas DeFi complexos, e como novas ameaças (exploração autônoma por IA) redefinem o conceito de "tempo de resposta".&lt;/p&gt;

&lt;p&gt;Para o desenvolvedor de 2025, escrever um smart contract seguro significa admitir que &lt;strong&gt;nenhum código é perfeito&lt;/strong&gt;. Significa construir dentro de uma estrutura que assume a falha, que monitora constantemente, que pode ser corrigida de forma ordenada, e que usa a tecnologia mais avançada disponível — tanto para atacar seus próprios contratos em simulação quanto para defendê-los em produção.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Just Code It Securely.&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Fontes de Referência:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://scs.owasp.org/sctop10/" rel="noopener noreferrer"&gt;OWASP Smart Contract Top 10 (2025)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.halborn.com/reports/top-100-defi-hacks-2025" rel="noopener noreferrer"&gt;Halborn Security Reports - Top 100 DeFi Hacks 2025&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://immunefi.com/research/" rel="noopener noreferrer"&gt;Immunefi Bug Bounty Research&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.openzeppelin.com/contracts/" rel="noopener noreferrer"&gt;OpenZeppelin Contracts Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://red.anthropic.com/2025/smart-contracts/" rel="noopener noreferrer"&gt;Anthropic Research: AI Agents Find $4.6M in Smart Contract Exploits&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>5 Técnicas Para Melhorar a Performance no seu App Angular</title>
      <dc:creator>Adriano P. Araujo</dc:creator>
      <pubDate>Thu, 27 Nov 2025 13:20:32 +0000</pubDate>
      <link>https://forem.com/dev-araujo/5-tecnicas-para-melhorar-a-performance-no-seu-app-angular-g0e</link>
      <guid>https://forem.com/dev-araujo/5-tecnicas-para-melhorar-a-performance-no-seu-app-angular-g0e</guid>
      <description>&lt;h2&gt;
  
  
  O Problema
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fzolzvmae6awi7ofmdq82.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fzolzvmae6awi7ofmdq82.webp" alt="muk" width="250" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lembra daquele app que começou rápido e depois foi ficando mais lento conforme adicionávamos features? Pois é, o culpado quase sempre é o mesmo: &lt;strong&gt;change detection&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O Angular, por padrão, é um pouco paranóico. A cada evento (scroll, clique, timer), ele verifica TODA a árvore de componentes pra ver se algo mudou.&lt;/p&gt;

&lt;p&gt;Traduzindo: se você tem 100 componentes e 100 eventos por segundo, são 10.000 verificações por segundo. Não tem CPU que aguente!&lt;/p&gt;

&lt;p&gt;Para resolver, listei abaixo 5 técnicas para melhorar a performance do seu app Angular. Algumas delas, mesmo sendo velhas conhecidas, ainda hoje costumam ser ignoradas.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. OnPush - A Estratégia Mais Importante
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Compatibilidade:&lt;/strong&gt; Angular 2+&lt;br&gt;
&lt;strong&gt;Impacto:&lt;/strong&gt; Reduz change detection em ~90%&lt;/p&gt;

&lt;p&gt;Essa aqui muda o jogo. O OnPush faz o Angular ser mais inteligente - ele só verifica mudanças quando realmente precisa.&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;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-user-card&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;div&amp;gt;{{ user.name }}&amp;lt;/div&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;changeDetection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ChangeDetectionStrategy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OnPush&lt;/span&gt;  &lt;span class="c1"&gt;// 👈 Essa mágica aqui&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;UserCardComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Input&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;User&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;A pegadinha:&lt;/strong&gt; Com OnPush, você precisa parar de mutar objetos:&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="c1"&gt;// ❌ Isso quebra tudo (o Angular não detecta)&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;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;João&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ Isso funciona perfeitamente&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;user&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="k"&gt;this&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="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;João&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;Recomendação:&lt;/strong&gt; Todo componente novo já deveria nascer com OnPush. Só remove quando realmente não tem jeito (e isso é raro).&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Signals - O Futuro Que Já Chegou
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Compatibilidade:&lt;/strong&gt; Angular 17+&lt;br&gt;
&lt;strong&gt;Impacto:&lt;/strong&gt; Mais eficiente que RxJS&lt;/p&gt;

&lt;p&gt;Signals são mais simples que RxJS e mais eficientes. Depois de testá-las, viram a primeira escolha para muitos devs.&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;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;div&amp;gt;Count: {{ count() }}&amp;lt;/div&amp;gt;    &amp;lt;!-- Note os () --&amp;gt;
    &amp;lt;div&amp;gt;Doubled: {{ doubled() }}&amp;lt;/div&amp;gt;
  `&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;CounterComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&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="c1"&gt;// 👈 Declaração simples&lt;/span&gt;
  &lt;span class="nx"&gt;doubled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;()&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="c1"&gt;// 👈 Computed elegante&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;Por que Signals sobre RxJS:&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="c1"&gt;// ❌ RxJS (funciona, mas é mais verboso)&lt;/span&gt;
&lt;span class="nx"&gt;count$&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;BehaviorSubject&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="nx"&gt;doubled$&lt;/span&gt; &lt;span class="o"&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;count$&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;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;c&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="c1"&gt;// ✅ Signals (mais simples e eficiente)&lt;/span&gt;
&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&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="nx"&gt;doubled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;()&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A grande vantagem: com Signals, só os componentes que usam aquele signal específico são verificados. É muito mais granular.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nota pra quem está em Angular 12-16:&lt;/strong&gt; RxJS + OnPush funciona muito bem também!&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Lazy Loading - Dividir para Conquistar
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Compatibilidade:&lt;/strong&gt; Angular 14+&lt;br&gt;
&lt;strong&gt;Impacto:&lt;/strong&gt; Isola componentes pesados&lt;/p&gt;

&lt;p&gt;Componentes pesados ou telas menos acessadas devem ser lazy-loaded:&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;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Routes&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;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;loadComponent&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="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./dashboard/dashboard.component&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;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DashboardComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// 👈 Só carrega quando acessado&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;Resultado:&lt;/strong&gt; O app principal fica leve e rápido. O dashboard só carrega quando o usuário realmente precisa.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Unsubscribe - Evitando Vazamentos
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Padrão recomendado (Clássico):&lt;/strong&gt; &lt;code&gt;takeUntil&lt;/code&gt; com Subject&lt;br&gt;
&lt;strong&gt;Padrão moderno (Angular 16+):&lt;/strong&gt; &lt;code&gt;takeUntilDestroyed&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Problema que resolve:&lt;/strong&gt; Memory leaks e change detection desnecessário&lt;/p&gt;

&lt;h3&gt;
  
  
  Abordagem Clássica (Angular 2+)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DataComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;OnDestroy&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;destroy$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Subject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// 👈 Subject de limpeza&lt;/span&gt;

  &lt;span class="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;()&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;dataService&lt;/span&gt;&lt;span class="p"&gt;.&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="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nf"&gt;takeUntil&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;destroy$&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// 👈 Limpa automaticamente&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&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="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;ngOnDestroy&lt;/span&gt;&lt;span class="p"&gt;()&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;destroy$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&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;destroy$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;complete&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;h3&gt;
  
  
  Abordagem Moderna (Angular 16+)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&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;takeUntilDestroyed&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;@angular/core/rxjs-interop&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="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;div&amp;gt;{{ data }}&amp;lt;/div&amp;gt;`&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;DataComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnInit&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;destroyRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;DestroyRef&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;data&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="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;dataService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DataService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;()&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;dataService&lt;/span&gt;&lt;span class="p"&gt;.&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="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nf"&gt;takeUntilDestroyed&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;destroyRef&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// 👈 Muito mais simples!&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&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="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;Por que funciona:&lt;/strong&gt; Observables que continuam emitindo depois que o componente foi destruído são uma fonte comum de problemas. Esse padrão elimina o problema.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qual usar?&lt;/strong&gt; Se você está em Angular 16+, use &lt;code&gt;takeUntilDestroyed&lt;/code&gt;. É mais limpo e não precisa implementar &lt;code&gt;OnDestroy&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. trackBy - O Segredo das Listas Rápidas
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Compatibilidade:&lt;/strong&gt; Angular 2+&lt;br&gt;
&lt;strong&gt;Quando usar:&lt;/strong&gt; Sempre em &lt;code&gt;*ngFor&lt;/code&gt; com listas dinâmicas&lt;br&gt;
&lt;strong&gt;Melhoria:&lt;/strong&gt; Listas com 1000+ itens ficam fluidas&lt;/p&gt;

&lt;h3&gt;
  
  
  Abordagem Clássica (Angular 2+)
&lt;/h3&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;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;div *ngFor="let user of users; trackBy: trackByFn"&amp;gt;
      {{ user.name }}
    &amp;lt;/div&amp;gt;`&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;UserListComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;users&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="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="c1"&gt;// 👈 Essa função simples faz mágica&lt;/span&gt;
  &lt;span class="nf"&gt;trackByFn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&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="nx"&gt;item&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;item&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="c1"&gt;// O Angular usa isso pra saber o que mudou&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;h3&gt;
  
  
  Abordagem Moderna com Control Flow (Angular 17+)
&lt;/h3&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;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    @for (user of users; track user.id) {
      &amp;lt;div&amp;gt;{{ user.name }}&amp;lt;/div&amp;gt;
    }
  `&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;UserListComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;users&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="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="c1"&gt;// 👈 Não precisa de trackByFn! O 'track' é obrigatório&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;Antes:&lt;/strong&gt; A lista inteira era re-renderizada a cada mudança&lt;br&gt;
&lt;strong&gt;Depois:&lt;/strong&gt; Só os itens que &lt;strong&gt;realmente mudaram&lt;/strong&gt; são atualizados&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nota importante:&lt;/strong&gt; No Angular 17+, o &lt;code&gt;track&lt;/code&gt; é &lt;strong&gt;obrigatório&lt;/strong&gt; na nova sintaxe de control flow (&lt;code&gt;@for&lt;/code&gt;). Isso força boas práticas de performance desde o início.&lt;/p&gt;




&lt;h2&gt;
  
  
  Checklist de Performance
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fqg0cnrw4mufv7hauktho.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fqg0cnrw4mufv7hauktho.gif" alt="checking" width="400" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Antes de entregar qualquer feature, é legal verificar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Todos componentes usando OnPush?&lt;/li&gt;
&lt;li&gt;Signals implementados (se Angular 17+)?&lt;/li&gt;
&lt;li&gt;Componentes pesados em lazy loading?&lt;/li&gt;
&lt;li&gt;Observables com takeUntil ou takeUntilDestroyed?&lt;/li&gt;
&lt;li&gt;O trackBy em todas as listas (ou &lt;a class="mentioned-user" href="https://dev.to/for"&gt;@for&lt;/a&gt; com track)?&lt;/li&gt;
&lt;li&gt;Testei no Performance Profiler?&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusão Prática
&lt;/h2&gt;

&lt;p&gt;Comece com OnPush em tudo. Depois adote Signals onde possível (Angular 17+). Finalmente, mantenha um processo consistente de lazy loading + unsubscribe + trackBy.&lt;/p&gt;

&lt;p&gt;Se você está em Angular 17+, aproveite as novas features: &lt;code&gt;takeUntilDestroyed&lt;/code&gt; e control flow com &lt;code&gt;@for&lt;/code&gt;. Elas tornam o código mais limpo e forçam boas práticas de performance.&lt;/p&gt;

&lt;p&gt;Os resultados? Apps que mantêm a performance não importa quantas features adicionemos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Just Code It!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>angular</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Adriano P. Araujo</dc:creator>
      <pubDate>Tue, 25 Nov 2025 23:08:05 +0000</pubDate>
      <link>https://forem.com/dev-araujo/-3kdk</link>
      <guid>https://forem.com/dev-araujo/-3kdk</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/dev-araujo/concorrencia-em-go-goroutines-e-channels-easy-i8g" class="crayons-story__hidden-navigation-link"&gt;Concorrência em Go: Goroutines e Channels Easy&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/dev-araujo" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F973209%2F49718ddc-dce8-4097-bfda-e17f027017d2.jpeg" alt="dev-araujo profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/dev-araujo" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Adriano P. Araujo
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Adriano P. Araujo
                
              
              &lt;div id="story-author-preview-content-3058838" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/dev-araujo" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F973209%2F49718ddc-dce8-4097-bfda-e17f027017d2.jpeg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Adriano P. Araujo&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/dev-araujo/concorrencia-em-go-goroutines-e-channels-easy-i8g" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Nov 25 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/dev-araujo/concorrencia-em-go-goroutines-e-channels-easy-i8g" id="article-link-3058838"&gt;
          Concorrência em Go: Goroutines e Channels Easy
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/go"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;go&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/backend"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;backend&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tutorial"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tutorial&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/goroutines"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;goroutines&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/dev-araujo/concorrencia-em-go-goroutines-e-channels-easy-i8g" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;4&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/dev-araujo/concorrencia-em-go-goroutines-e-channels-easy-i8g#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            7 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




</description>
      <category>go</category>
      <category>backend</category>
      <category>tutorial</category>
      <category>goroutines</category>
    </item>
    <item>
      <title>Concorrência em Go: Goroutines e Channels Easy</title>
      <dc:creator>Adriano P. Araujo</dc:creator>
      <pubDate>Tue, 25 Nov 2025 20:16:24 +0000</pubDate>
      <link>https://forem.com/dev-araujo/concorrencia-em-go-goroutines-e-channels-easy-i8g</link>
      <guid>https://forem.com/dev-araujo/concorrencia-em-go-goroutines-e-channels-easy-i8g</guid>
      <description>&lt;h2&gt;
  
  
  Antes de Começar: Concorrência vs Paralelismo vs Assíncrono
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fzrh4w7lpxlqa6eplbanw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fzrh4w7lpxlqa6eplbanw.jpg" alt="Qual a diferênça?" width="600" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Essas três palavrinhas são frequentemente confundidas, especialmente se você vem do JavaScript. Vamos descomplicar:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concorrência&lt;/strong&gt; é quando você ORGANIZA seu programa para lidar com várias tarefas. Não significa que rodam ao mesmo tempo, mas que o programa sabe alternar entre elas. É sobre ORQUESTRAÇÃO.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paralelismo&lt;/strong&gt; é quando várias tarefas REALMENTE rodam ao mesmo tempo, em processadores diferentes. É sobre EXECUÇÃO SIMULTÂNEA.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Código assíncrono&lt;/strong&gt; (como no JavaScript) é quando você escreve código que não bloqueia. Você chama uma função, ela retorna uma Promise, e você continua fazendo outras coisas enquanto espera. Mas na prática, tudo roda em uma ÚNICA thread.&lt;/p&gt;

&lt;p&gt;A diferença prática?&lt;/p&gt;

&lt;p&gt;Em JavaScript (Node.js), quando você faz:&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;await&lt;/span&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="s1"&gt;api1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&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="s1"&gt;api2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&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="s1"&gt;api3&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;Você está sendo assíncrono, mas não paralelo. As requisições não rodam simultaneamente - o event loop vai alternando entre elas.&lt;/p&gt;

&lt;p&gt;Em Go, quando você faz:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;buscarAPI1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;buscarAPI2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;buscarAPI3&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você está sendo concorrente. E a mágica é: dependendo do seu processador, essas goroutines podem rodar em paralelo (simultaneamente em diferentes núcleos) ou o Go pode simplesmente alternar entre elas.&lt;/p&gt;

&lt;p&gt;O melhor de tudo? Você não precisa se preocupar com isso. O runtime do Go cuida de tudo pra você!&lt;/p&gt;




&lt;h2&gt;
  
  
  O Problema Real
&lt;/h2&gt;

&lt;p&gt;Quando você começa com Go, logo bate aquela dúvida: "Como faço para executar várias tarefas ao mesmo tempo sem criar uma zona?"&lt;/p&gt;

&lt;p&gt;Em linguagens como Python ou Node.js, você pode se perder em callbacks, Promises ou async/await. Em Go, a resposta é elegantemente simples: &lt;strong&gt;goroutines&lt;/strong&gt; e &lt;strong&gt;channels&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Mas antes do código, vamos entender o problema que essas ferramentas resolvem.&lt;/p&gt;

&lt;p&gt;Imagine que você está construindo um sistema que precisa buscar dados de várias APIs ao mesmo tempo. Sem concorrência, seria assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Sequencial - muito lento&lt;/span&gt;
&lt;span class="n"&gt;resultado1&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;buscarDadosAPI1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c"&gt;// 2 segundos&lt;/span&gt;
&lt;span class="n"&gt;resultado2&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;buscarDadosAPI2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c"&gt;// 2 segundos  &lt;/span&gt;
&lt;span class="n"&gt;resultado3&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;buscarDadosAPI3&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c"&gt;// 2 segundos&lt;/span&gt;
&lt;span class="c"&gt;// Total: 6 segundos 😴&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com concorrência, você pode fazer tudo simultaneamente. Vou mostrar o código real agora:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Concorrente - muito mais rápido!&lt;/span&gt;
&lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;buscarDadosAPI1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}()&lt;/span&gt;
&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;buscarDadosAPI2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}()&lt;/span&gt; 
&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;buscarDadosAPI3&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}()&lt;/span&gt;

&lt;span class="c"&gt;// Todas as APIs são chamadas ao mesmo tempo&lt;/span&gt;
&lt;span class="n"&gt;res1&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;resultado&lt;/span&gt;  &lt;span class="c"&gt;// ~2 segundos&lt;/span&gt;
&lt;span class="n"&gt;res2&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;resultado&lt;/span&gt;  &lt;span class="c"&gt;// ~2 segundos&lt;/span&gt;
&lt;span class="n"&gt;res3&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;resultado&lt;/span&gt;  &lt;span class="c"&gt;// ~2 segundos&lt;/span&gt;
&lt;span class="c"&gt;// Total: ~2 segundos! 🚀&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa é a mágica que vamos desvendar!&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é uma Goroutine?
&lt;/h2&gt;

&lt;p&gt;Uma &lt;strong&gt;goroutine&lt;/strong&gt; é basicamente uma função que executa de forma independente das outras. É super leve, eficiente e gerenciada pelo próprio Go.&lt;/p&gt;

&lt;p&gt;A sintaxe é tão simples que chega a ser engraçada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;minhaFuncao&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É só colocar &lt;code&gt;go&lt;/code&gt; na frente da chamada da função. Pronto! Ela vai rodar em paralelo.&lt;/p&gt;

&lt;p&gt;Mas aí vem a pergunta: como você sabe quando a goroutine terminou? Como pega o resultado dela?&lt;/p&gt;

&lt;p&gt;É aí que entram os &lt;strong&gt;channels&lt;/strong&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Channels: A Comunicação Entre Goroutines
&lt;/h2&gt;

&lt;p&gt;Um &lt;strong&gt;channel&lt;/strong&gt; é como um tubo de comunicação entre goroutines. Uma goroutine coloca dados dentro, outra goroutine pega dados de fora. É seguro, sincronizado e evita aqueles bugs malucos de concorrência.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;À partir daqui os exemplos dados são baseados no uso de Data-feeds da chainlink, então se você não sabe o que é isso ou quiser ter mais contexto, eu explico &lt;a href="https://dev.to/dev-araujo/como-integrar-chainlink-data-feeds-em-go-para-multiplos-tokens-ekb"&gt;aqui&lt;/a&gt; 😉&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vamos criar um exemplo prático:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"context"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"math/big"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/ethereum/go-ethereum/common"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/ethereum/go-ethereum/ethclient"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/aggregator_v3_interface"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// TokenConfig guarda as informações de cada token que queremos monitorar&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;TokenConfig&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Symbol&lt;/span&gt;  &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Address&lt;/span&gt; &lt;span class="n"&gt;common&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// FormattedPrice armazena o preço formatado e outras infos úteis&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;FormattedPrice&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Symbol&lt;/span&gt;    &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Price&lt;/span&gt;     &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Float&lt;/span&gt;
    &lt;span class="n"&gt;Timestamp&lt;/span&gt; &lt;span class="kt"&gt;uint64&lt;/span&gt;
    &lt;span class="n"&gt;Decimals&lt;/span&gt;  &lt;span class="kt"&gt;uint8&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos para a função &lt;code&gt;main&lt;/code&gt;. Aqui nos conectamos à rede Ethereum e definimos quais tokens queremos monitorar. Sinta-se à vontade para adicionar ou remover tokens!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Conectando a um nó da Ethereum&lt;/span&gt;
    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ethclient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://ethereum-rpc.publicnode.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ops! Deu ruim ao conectar na Ethereum: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Nossa lista de tokens para monitorar! Adicione os que quiser aqui.&lt;/span&gt;
    &lt;span class="n"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;TokenConfig&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"ETH"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;common&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HexToAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419"&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"BTC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;common&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HexToAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c"&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"LINK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;common&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HexToAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0x2c1d072e956AFFC0D435Cb7AC38EF18d24d9127c"&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Este canal vai receber os preços conforme forem sendo encontrados&lt;/span&gt;
    &lt;span class="n"&gt;pricesChan&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="n"&gt;FormattedPrice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c"&gt;// Um contexto com timeout para não ficarmos esperando eternamente&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Lança uma goroutine para cada token - todas rodam ao mesmo tempo!&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;fetchTokenPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pricesChan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Agora é só coletar os resultados que forem chegando&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🎯 Buscando preços em paralelo..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;pricesChan&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"✅ %s: $%.2f (Atualizado: %d)&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"⏰ Timeout! Demorou demais: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Err&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="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🎉 Todos os preços foram coletados!"&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 &lt;code&gt;fetchTokenPrice&lt;/code&gt; é onde a mágica acontece - ela interage com o contrato na blockchain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// fetchTokenPrice é nossa trabalhadora: busca o preço de um token específico&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;fetchTokenPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ethclient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="n"&gt;TokenConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pricesChan&lt;/span&gt; &lt;span class="k"&gt;chan&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;FormattedPrice&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Cria uma instância do contrato para podermos conversar com ele&lt;/span&gt;
    &lt;span class="n"&gt;aggregator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;aggregator_v3_interface&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewAggregatorV3Interface&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"❌ Erro no contrato do %s: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&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="c"&gt;// Pega os dados mais recentes do oráculo&lt;/span&gt;
    &lt;span class="n"&gt;roundData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;aggregator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LatestRoundData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"❌ Erro buscando dados do %s: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&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="c"&gt;// Descobre quantas casas decimais o preço tem&lt;/span&gt;
    &lt;span class="n"&gt;decimals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;aggregator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Decimals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"❌ Erro nas casas decimais do %s: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&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="c"&gt;// Converte o preço para um formato que a gente entende&lt;/span&gt;
    &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;roundData&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Answer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;divisor&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decimals&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Quo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;divisor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Manda o resultado pelo canal&lt;/span&gt;
    &lt;span class="n"&gt;pricesChan&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;FormattedPrice&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Price&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;roundData&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UpdatedAt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Uint64&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;Decimals&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;decimals&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;O que está rolando aqui?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Criamos um &lt;code&gt;channel&lt;/code&gt; chamado &lt;code&gt;pricesChan&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Lançamos várias goroutines, cada uma busca um token diferente&lt;/li&gt;
&lt;li&gt;Cada goroutine manda seu resultado pelo channel&lt;/li&gt;
&lt;li&gt;Na &lt;code&gt;main&lt;/code&gt;, vamos coletando os resultados conforme chegam&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A parte &lt;code&gt;&amp;lt;-pricesChan&lt;/code&gt; espera até chegar um valor no channel. Assim o programa não termina antes de todas as goroutines terminarem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Padrão Prático: Timeout com Context
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fgabx3jop4q9eg33x2d9g.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fgabx3jop4q9eg33x2d9g.jpg" alt="esperando" width="498" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na vida real, você não quer que seu programa fique esperando eternamente. Quer um tempo limite. É aí que o &lt;code&gt;context&lt;/code&gt; salva:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"context"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;buscarDado&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Simula um trabalho que demora&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Dado %d pronto!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="c"&gt;// Tudo certo, mandamos o resultado&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="c"&gt;// Opa, o contexto foi cancelado! Melhor abortar.&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"✂️ Goroutine %d foi cancelada&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&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="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Contexto com timeout de 2 segundos (bem curto pra forçar o cancelamento)&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Lança algumas goroutines&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;buscarDado&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resultado&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Tenta coletar os resultados&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;resultado&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"⏰ Timeout! Chega de esperar..."&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui, se as goroutines demorarem mais de 2 segundos, o contexto cancela e a gente para de esperar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Buffered Channels: Quando Você Quer Mais Flexibilidade 🤸‍♂️
&lt;/h2&gt;

&lt;p&gt;Até agora usamos channels "normais". Isso significa que a goroutine que envia fica esperando até alguém receber.&lt;/p&gt;

&lt;p&gt;Mas às vezes você quer que a goroutine envie e já continue trabalhando. Para isso, usamos &lt;strong&gt;buffered channels&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Channel com buffer para 3 valores&lt;/span&gt;
&lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// Agora você pode enviar 3 valores sem ficar esperando&lt;/span&gt;
&lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="s"&gt;"valor 1"&lt;/span&gt;
&lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="s"&gt;"valor 2"&lt;/span&gt; 
&lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="s"&gt;"valor 3"&lt;/span&gt;

&lt;span class="c"&gt;// Só vai travar na 4ª tentativa (quando o buffer estiver cheio)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Padrão Real: Agregando Dados de Várias Fontes
&lt;/h2&gt;

&lt;p&gt;Vamos juntar tudo em um exemplo mais próximo da realidade. Imagine buscando preços de criptomoedas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"context"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Preco&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Moeda&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Valor&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;buscarPreco&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;moeda&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="n"&gt;Preco&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Simula uma chamada de API que demora 1 segundo&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Preços fictícios para exemplo&lt;/span&gt;
    &lt;span class="n"&gt;precos&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"BTC"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;45000.50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"ETH"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3200.75&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="s"&gt;"LINK"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;18.25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;Preco&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Moeda&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;moeda&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Valor&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;precos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;moeda&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"✅ Preço do %s buscado com sucesso&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;moeda&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"❌ Busca do %s cancelada&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;moeda&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="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;moedas&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"BTC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"ETH"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"LINK"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="n"&gt;Preco&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;moedas&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Dispara uma goroutine para cada moeda&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;moeda&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;moedas&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;buscarPreco&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;moeda&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resultado&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Coleta os resultados&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"📊 Coletando preços..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;moedas&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;preco&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;resultado&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"💰 %s: $%.2f&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;preco&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Moeda&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;preco&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Valor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🎉 Todos os preços coletados!"&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;h2&gt;
  
  
  Por Que Go é Tão Bom Nisso?
&lt;/h2&gt;

&lt;p&gt;Go brilha em concorrência porque:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Goroutines são super leves&lt;/strong&gt;: você pode ter milhares sem pesar no sistema&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Channels são seguros&lt;/strong&gt;: sem aqueles bugs malucos de acesso simultâneo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sintaxe é simples&lt;/strong&gt;: não tem callback hell ou Promises complexas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;O runtime cuida de tudo&lt;/strong&gt;: você só manda e o Go gerencia&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Embora concorrência em Go seja algo complexo para quem não está acostumado, ele é um modelo bem pensado onde goroutines trabalham independentemente e channels as mantêm sincronizadas.&lt;/p&gt;

&lt;p&gt;Comece simples: uma goroutine, um channel, um resultado. Depois evolua para timeouts, buffered channels e agregação de dados.&lt;/p&gt;

&lt;p&gt;O legal é que mesmo em cenários complexos, o código em Go continua legível e direto ao ponto. 💙&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Just Code It! 🚀&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>backend</category>
      <category>tutorial</category>
      <category>goroutines</category>
    </item>
    <item>
      <title>A Usabilidade no Back-End</title>
      <dc:creator>Adriano P. Araujo</dc:creator>
      <pubDate>Thu, 23 Oct 2025 13:18:48 +0000</pubDate>
      <link>https://forem.com/dev-araujo/a-usabilidade-no-back-end-12ll</link>
      <guid>https://forem.com/dev-araujo/a-usabilidade-no-back-end-12ll</guid>
      <description>&lt;h2&gt;
  
  
  A Usabilidade para além do Front-end
&lt;/h2&gt;

&lt;p&gt;Quando falamos em "usabilidade", é quase automático pensarmos em interfaces bonitas, botões no lugar certo e telas que respondem rapidamente. Em resumo: &lt;strong&gt;a experiência do usuário final.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mas e se eu disser que a usabilidade é um conceito que deveria ser aplicado &lt;strong&gt;muito antes&lt;/strong&gt; do front-end? Que ela começa no coração do sistema: &lt;strong&gt;o back-end&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Um back-end com boa usabilidade não é sobre ter uma "interface gráfica bonita" (afinal, o "usuário" aqui é, na maioria das vezes, outro desenvolvedor ou sistema). É sobre criar uma experiência fluida, intuitiva e eficiente para &lt;strong&gt;quem vai consumir, manter e expandir o seu código&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F245jbqntptcnmjq56xff.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F245jbqntptcnmjq56xff.jpg" alt="overcooked" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pense no back-end como a cozinha de um restaurante. O cliente (o Front-end) só vê o prato lindo e saboroso. Mas se a cozinha (Back-end) for bagunçada, com facas cegas e panelas queimadas, o prato vai demorar, sair errado ou, pior, o restaurante vai fechar as portas.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é "Usabilidade no Back-End"?
&lt;/h2&gt;

&lt;p&gt;Chamamos isso de &lt;strong&gt;Developer Experience (DX)&lt;/strong&gt; ou "Experiência do Desenvolvedor". É a usabilidade aplicada à API, ao código, à arquitetura. É o que permite que a gente, devs, consiga programar mais e &lt;em&gt;gastar menos tempo perguntando "como funciona isso?"&lt;/em&gt; ou tentando agendar uma &lt;em&gt;call&lt;/em&gt; para entender como determinado payload deve ser .&lt;/p&gt;

&lt;p&gt;Um back-end com boa DX possui três pilares que precisam ser &lt;strong&gt;impecáveis&lt;/strong&gt;:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. O Contrato Sagrado: Uma API Intuitiva e Bem Documentada
&lt;/h2&gt;

&lt;p&gt;Na minha jornada com &lt;strong&gt;Solidity&lt;/strong&gt; (sempre falando de web3 neh? relaxa que é rapidão), e integrando serviços como os &lt;strong&gt;Chainlink Data Feeds&lt;/strong&gt;, aprendi que um contrato mal feito é o caos.&lt;/p&gt;

&lt;p&gt;Na Web3, o &lt;strong&gt;ABI (Application Binary Interface)&lt;/strong&gt; de um contrato inteligente é o &lt;em&gt;seu contrato&lt;/em&gt;. Ele define como o mundo se comunica com seu código &lt;em&gt;on-chain&lt;/em&gt;. Na arquitetura tradicional, sua API REST/GraphQL é exatamente isso: &lt;strong&gt;o seu contrato sagrado&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;URLs e Endpoints Claros:&lt;/strong&gt; 

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET /users/{id}&lt;/code&gt; é intuitivo.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /getUserDataById.php?uid=123&lt;/code&gt; não é . &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Seu cliente, seja o front-end em Angular ou um serviço em Go, não deveria ficar perdendo tempo tentando adivinhar o endpoint correto 🫠.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Respostas Consistentes:&lt;/strong&gt; Sempre retorne JSON no mesmo &lt;strong&gt;formato&lt;/strong&gt;.&lt;br&gt;
Inclua códigos de status HTTP significativos (200, 201, 400, 404, 500). Nada é pior do que um &lt;code&gt;200 OK&lt;/code&gt; que te devolve um erro 👀 (quem nunca).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Documentação Viva (OpenAPI/Swagger):&lt;/strong&gt; A documentação deve ser o seu &lt;em&gt;single source of truth&lt;/em&gt;. Não pode ser um PDF estático de três meses atrás. &lt;strong&gt;A DX exige que a documentação acompanhe o código.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Mensagens de Erro que Ajudam de Verdade
&lt;/h2&gt;

&lt;p&gt;Mensagens de erro no back-end são um ponto de contato direto com o desenvolvedor que está consumindo a API. Elas são a forma mais rápida de sabotar ou acelerar a DX.&lt;/p&gt;

&lt;p&gt;Compare:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Inútil (e frustrante):&lt;/strong&gt; &lt;code&gt;"Error: Null Exception"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Útil (economiza horas):&lt;/strong&gt; &lt;code&gt;"Erro ao criar usuário. O campo 'email' é obrigatório e não pode ser nulo. Veja a documentação em /docs/users#create."&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F90s1j690ku1xn6svyzwu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F90s1j690ku1xn6svyzwu.gif" alt="mensagens de erro" width="341" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Dev Front-end ao receber receber mensagem de erro humanamente ilegível&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mensagens de erro claras economizam &lt;strong&gt;horas&lt;/strong&gt; de debug e tornam a integração com o front-end muito mais rápida. &lt;strong&gt;Elas transformam um obstáculo em um caminho.&lt;/strong&gt; 🧘🏻‍♂️𓅓&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Código Limpo, Arquitetura Sólida (E a Mão do Gemini)
&lt;/h2&gt;

&lt;p&gt;A verdadeira usabilidade no back-end mora na &lt;strong&gt;estrutura interna&lt;/strong&gt;. Com minha experiência migrando aplicações e atuando em ambientes de missão crítica, percebi que o custo de um código desorganizado é altíssimo. É aí que a filosofia &lt;strong&gt;SOLID&lt;/strong&gt; e a busca por baixo acoplamento entram:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;SOLID e Simplicidade:&lt;/strong&gt; É possível trocar um banco de dados de MySQL para PostgreSQL no seu projeto? Se não for, a usabilidade arquitetural é baixa. Linguagens como &lt;strong&gt;Go&lt;/strong&gt; nos forçam a pensar em simplicidade e concorrência, o que naturalmente eleva a DX.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Código Legível e Componentizado:&lt;/strong&gt; No Front-end (com Angular), aprendemos o valor de componentes reutilizáveis. No Back-end, isso se traduz em classes e funções de responsabilidade única.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consistência é uma Ferramenta de DX:&lt;/strong&gt; Um código só é usável se ele for consistente. Para garantir isso, a &lt;strong&gt;automação&lt;/strong&gt; é essencial. É por isso que uso ferramentas como o &lt;strong&gt;Gemini Code Assist&lt;/strong&gt; e padrões como o &lt;code&gt;styleguide.md&lt;/code&gt;. O robô vira o &lt;strong&gt;fiscal do padrão&lt;/strong&gt; e garante que a qualidade (aquela que buscamos com Jest e SonarQube) seja mantida em todas as &lt;em&gt;layers&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Escrevi um artigo sobre o Gemini Code Assist &lt;a href="https://dev.to/dev-araujo/revisao-automatica-de-prs-no-github-com-gemini-code-assist-241nc"&gt;aqui&lt;/a&gt;, talvez seja útil.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Zero Burocracia no Setup
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F28zo26etfqmjz2m58rxs.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F28zo26etfqmjz2m58rxs.webp" alt="love docker" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A primeira interação de um novo desenvolvedor com seu projeto é o &lt;em&gt;setup&lt;/em&gt;. Se ele passar um dia inteiro configurando variáveis de ambiente e banco de dados, a DX já começou com o pé esquerdo.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;"Dockerize" é Mandatório:&lt;/strong&gt; Um simples &lt;code&gt;docker-compose up&lt;/code&gt; deve ser suficiente para levantar todo o ambiente de desenvolvimento. Esse é um padrão que a formação &lt;strong&gt;Full Cycle&lt;/strong&gt; reforça e que todo projeto moderno precisa.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Health Checks e Logs:&lt;/strong&gt; Crie endpoints simples como &lt;code&gt;/health&lt;/code&gt; ou &lt;code&gt;/status&lt;/code&gt; que mostram se o sistema e suas dependências estão saudáveis. Se uma requisição está lenta, os logs devem dizer o porquê: &lt;em&gt;"Query no banco demorou 2000ms para o usuário ID: 456"&lt;/em&gt;. Performance que não é um segredo é boa usabilidade!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Por Que Se Importar com Isso?
&lt;/h2&gt;

&lt;p&gt;A usabilidade no back-end é um investimento que paga dividendos enormes ao longo do ciclo de vida do software:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Velocidade na Equipe:&lt;/strong&gt; O Front-end consegue integrar com o Back-end sem ficar gritando "como funciona essa API?!"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manutenção Mais Barata:&lt;/strong&gt; Código legível e bem estruturado é mais fácil (e mais barato) de manter e escalar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Atração e Retenção de Talentos:&lt;/strong&gt; Desenvolvedores &lt;strong&gt;amam&lt;/strong&gt; trabalhar em projetos bem estruturados. Um bom back-end é o seu cartão de visitas mais valioso (Mais sobre isso na listinha de leitura abaixo 😊)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Algumas Leituras Que Podem Ajudar
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://about.gitlab.com/topics/devops/what-is-developer-experience/" rel="noopener noreferrer"&gt;What is developer experience&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.atlassian.com/developer-experience" rel="noopener noreferrer"&gt;What is developer experience &amp;amp; why is it important?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/pt-br/azure/architecture/best-practices/api-design" rel="noopener noreferrer"&gt;Práticas recomendadas para design de API Web RESTful&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://avera.com.br/blog/api-restful-boas-praticas****" rel="noopener noreferrer"&gt;API RESTful - Boas práticas&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.luizfernandodev.com.br/principios-solid-para-que-serve-entenda/" rel="noopener noreferrer"&gt;Princípios SOLID, para que serve? Entenda&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/inside-picpay/documenta%C3%A7%C3%A3o-de-apis-voc%C3%AA-conhece-o-swagger-fd8b403d27ed" rel="noopener noreferrer"&gt;Documentação de APIs: você conhece o Swagger?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ff0tp9q2glqihb94pxc6a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ff0tp9q2glqihb94pxc6a.png" alt="Think guy" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Concluindo:
&lt;/h2&gt;

&lt;p&gt;A usabilidade no back-end é uma mudança de &lt;strong&gt;mentalidade&lt;/strong&gt;: parar de pensar no código como uma "caixa preta" e começar a vê-lo como um &lt;strong&gt;produto&lt;/strong&gt; cujo &lt;strong&gt;cliente é outro desenvolvedor&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;No final das contas, um sistema só é verdadeiramente usável quando é usável &lt;strong&gt;em todas as suas camadas&lt;/strong&gt;. E a &lt;strong&gt;Developer Experience&lt;/strong&gt; é a métrica que garante o sucesso de todos nós.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Just Code It!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>development</category>
      <category>backend</category>
      <category>devex</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Consultando Preços de Criptomoedas com Chainlink e Golang</title>
      <dc:creator>Adriano P. Araujo</dc:creator>
      <pubDate>Tue, 23 Sep 2025 18:09:02 +0000</pubDate>
      <link>https://forem.com/dev-araujo/como-integrar-chainlink-data-feeds-em-go-para-multiplos-tokens-ekb</link>
      <guid>https://forem.com/dev-araujo/como-integrar-chainlink-data-feeds-em-go-para-multiplos-tokens-ekb</guid>
      <description>&lt;p&gt;Desenvolvedores que atuam no ecossistema blockchain frequentemente enfrentam um desafio comum:  &lt;strong&gt;como obter dados do mundo real, como preços de ativos, de forma segura e confiável dentro de uma aplicação descentralizada.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;A dependência de serviços centralizados pode criar um ponto de falha, e as limitações de planos gratuitos podem ser um obstáculo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fs4uzus3vt3x38jikhnii.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fs4uzus3vt3x38jikhnii.gif" alt="Ah o nervosismo do dev blockchain que não usa a Chainlink" width="220" height="235"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;&lt;a href="https://docs.chain.link/data-feeds" rel="noopener noreferrer"&gt;Chainlink Data Feeds&lt;/a&gt;&lt;/strong&gt; surge como uma solução robusta para esse problema, oferecendo dados descentralizados e auditáveis diretamente on-chain.&lt;/p&gt;

&lt;p&gt;Neste guia, construiremos uma aplicação em &lt;strong&gt;Golang&lt;/strong&gt; para consultar os preços de múltiplos tokens de forma concorrente e eficiente, utilizando a infraestrutura da Chainlink.&lt;/p&gt;

&lt;h2&gt;
  
  
  Entendendo a Chainlink e o "Problema do Oráculo"
&lt;/h2&gt;

&lt;p&gt;Por padrão, blockchains são sistemas isolados; elas não conseguem acessar dados de sistemas externos (off-chain). Essa limitação é conhecida como o &lt;strong&gt;"problema do oráculo"&lt;/strong&gt;. Como um contrato inteligente pode saber o preço do Ethereum em dólar se ele não pode "olhar" para fora da blockchain?&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;&lt;a href="https://chain.link/" rel="noopener noreferrer"&gt;Chainlink&lt;/a&gt;&lt;/strong&gt; resolve exatamente isso. Ela é uma rede de oráculos descentralizada que atua como uma ponte segura entre as blockchains (on-chain) e fontes de dados do mundo real (off-chain). Ela permite que contratos inteligentes reajam a dados, eventos e pagamentos externos de forma confiável e à prova de adulteração.&lt;/p&gt;

&lt;p&gt;Os &lt;strong&gt;Data Feeds&lt;/strong&gt; são um dos serviços mais populares da Chainlink. Eles são redes de oráculos descentralizadas que fornecem informações de preços de ativos para contratos inteligentes, agregando dados de múltiplas fontes (e é totalmente &lt;em&gt;free&lt;/em&gt;). &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fe1auiwrugxqnc5vdycxn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fe1auiwrugxqnc5vdycxn.png" alt="O gato cigano está consultando a chainlink" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora vamos deixar de papinho e vamos ao código!&lt;/p&gt;




&lt;h3&gt;
  
  
  ⚙️ Pré-requisitos
&lt;/h3&gt;

&lt;p&gt;Antes de iniciarmos, certifique-se de que seu ambiente de desenvolvimento atende aos seguintes requisitos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Go instalado&lt;/strong&gt; (versão 1.21 ou superior).&lt;/li&gt;
&lt;li&gt;Um &lt;strong&gt;provedor de RPC Ethereum&lt;/strong&gt;. Utilizaremos um endpoint público para este guia, mas para aplicações em produção, recomenda-se serviços dedicados como Infura ou Alchemy.&lt;/li&gt;
&lt;li&gt;Os &lt;strong&gt;endereços dos contratos&lt;/strong&gt; dos Data Feeds. Consulte a &lt;a href="https://docs.chain.link/data-feeds/price-feeds/addresses" rel="noopener noreferrer"&gt;página oficial de endereços&lt;/a&gt; para obter os contratos corretos para a rede desejada (ex: Ethereum Mainnet, Sepolia).&lt;/li&gt;
&lt;li&gt;Conhecimento básico de Golang e da interação com contratos inteligentes.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  1. Configuração do Projeto
&lt;/h2&gt;

&lt;p&gt;Inicie criando um diretório para o projeto e inicializando um módulo Go.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;chainlink-price-feed
&lt;span class="nb"&gt;cd &lt;/span&gt;chainlink-price-feed
go mod init chainlink-price-feed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Instalação das Dependências
&lt;/h2&gt;

&lt;p&gt;Precisamos das bibliotecas &lt;code&gt;go-ethereum&lt;/code&gt; para interagir com a blockchain e do pacote da Chainlink que contém as interfaces dos contratos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go get github.com/ethereum/go-ethereum
go get github.com/ethereum/go-ethereum/ethclient
go get github.com/smartcontractkit/chainlink/core/gethwrappers/generated/aggregator_v3_interface
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Estruturando o Código
&lt;/h2&gt;

&lt;p&gt;Vamos construir nosso arquivo &lt;code&gt;main.go&lt;/code&gt; aos poucos. Assim, você entende o propósito de cada trecho antes de ver o monstro completo.&lt;/p&gt;

&lt;p&gt;Primeiro, vamos definir as estruturas que organizarão nossos dados. Uma (&lt;code&gt;TokenConfig&lt;/code&gt;) para guardar o nome e o endereço de cada token e outra (&lt;code&gt;PreçoFormatado&lt;/code&gt;) para armazenar o resultado bonitinho que receberemos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"context"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"math/big"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/ethereum/go-ethereum/common"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/ethereum/go-ethereum/ethclient"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/aggregator_v3_interface"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// TokenConfig armazena a configuração de cada token que desejamos monitorar.&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;TokenConfig&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Symbol&lt;/span&gt;  &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Address&lt;/span&gt; &lt;span class="n"&gt;common&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// FormattedPrice guarda o preço final e outras informações úteis.&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;FormattedPrice&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Symbol&lt;/span&gt;    &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Price&lt;/span&gt;     &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Float&lt;/span&gt;
    &lt;span class="n"&gt;Timestamp&lt;/span&gt; &lt;span class="kt"&gt;uint64&lt;/span&gt;
    &lt;span class="n"&gt;Decimals&lt;/span&gt;  &lt;span class="kt"&gt;uint8&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, vamos começar a função &lt;code&gt;main&lt;/code&gt;. Aqui, nós nos conectamos à rede Ethereum e definimos quais tokens queremos monitorar. Sinta-se à vontade para adicionar ou remover tokens desta lista!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Conectando a um nó da Ethereum. Este endpoint público é ótimo para      começar.&lt;/span&gt;
    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ethclient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://ethereum-rpc.publicnode.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ops! Deu ruim ao conectar no Ethereum: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Nossa lista de alvos! Adicione quantos tokens quiser aqui.&lt;/span&gt;
    &lt;span class="c"&gt;// Esses endereços são endereços da MAINNET.&lt;/span&gt;
    &lt;span class="n"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;TokenConfig&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"ETH"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;common&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HexToAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419"&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"BTC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;common&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HexToAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c"&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"LINK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;common&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HexToAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0x2c1d072e956AFFC0D435Cb7AC38EF18d24d9127c"&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;Para buscar os preços de forma eficiente, vamos usar a mágica da concorrência em Go. Lançaremos uma busca para cada token ao mesmo tempo (&lt;code&gt;goroutine&lt;/code&gt;). Para receber os resultados de volta de forma organizada e segura, usaremos um canal (&lt;code&gt;channel&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Também adicionamos um &lt;code&gt;context&lt;/code&gt; com &lt;em&gt;timeout&lt;/em&gt;, uma espécie de cronômetro de segurança para garantir que nosso programa não fique esperando para sempre se a rede estiver lenta.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;    &lt;span class="c"&gt;// ... continuando dentro da função main()&lt;/span&gt;
    &lt;span class="c"&gt;// Este canal vai receber os preços assim que eles foremencontrados.&lt;/span&gt;
    &lt;span class="n"&gt;pricesChan&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="n"&gt;FormattedPrice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c"&gt;// Um contexto com timeout para não ficarmos presos esperando para   sempre. :p&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Lança uma "missão" para buscar o preço de cada token, tudo ao mesmo tempo.&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;fetchTokenPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pricesChan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Agora, a gente espera e coleta os resultados que chegam pelo canal.&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Buscando preços..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;pricesChan&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"✅ Preço do %s: %.2f USD (Atualizado em: %d)&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Demorou demais! O timeout foi atingido: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Err&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;A função &lt;code&gt;fetchTokenPrice&lt;/code&gt; contém a lógica de interação com o contrato. Ela instancia o contrato, chama a função &lt;code&gt;latestRoundData&lt;/code&gt; e formata o valor retornado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// fetchTokenPrice é o nosso "operário": ele busca o preço de um token específico.&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;fetchTokenPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ethclient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="n"&gt;TokenConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pricesChan&lt;/span&gt; &lt;span class="k"&gt;chan&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;FormattedPrice&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Cria uma instância do contrato para a gente poder interagir com ele.&lt;/span&gt;
    &lt;span class="n"&gt;aggregator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;aggregator_v3_interface&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewAggregatorV3Interface&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Erro ao instanciar o contrato para %s: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&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="c"&gt;// Pega os dados mais recentes do oráculo.&lt;/span&gt;
    &lt;span class="n"&gt;roundData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;aggregator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LatestRoundData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Erro ao buscar os dados para %s: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&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="c"&gt;// Descobre quantas casas decimais o preço tem.&lt;/span&gt;
    &lt;span class="n"&gt;decimals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;aggregator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Decimals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Erro ao buscar as casas decimais para %s: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&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="c"&gt;// O preço vem como um número inteiro gigante. A gente precisa formatá-lo.&lt;/span&gt;
    &lt;span class="n"&gt;priceFloat&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;roundData&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Answer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;divisor&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decimals&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;formattedPrice&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Quo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;priceFloat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;divisor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Envia o resultado bonitão de volta para a função main através do canal.&lt;/span&gt;
    &lt;span class="n"&gt;pricesChan&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;FormattedPrice&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Price&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;formattedPrice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;roundData&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UpdatedAt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Uint64&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;Decimals&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;decimals&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;h2&gt;
  
  
  4. Código Completo (&lt;code&gt;main.go&lt;/code&gt;)
&lt;/h2&gt;

&lt;p&gt;Ufa! Agora que você entendeu cada parte,ou ao menos eu acho que sim &lt;br&gt;
🤔, aqui está o arquivo &lt;code&gt;main.go&lt;/code&gt; completo para você copiar e colar (talvez só essa parte te interesse 🥺):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"context"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"math/big"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/ethereum/go-ethereum/common"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/ethereum/go-ethereum/ethclient"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/smartcontractkit/chainlink/core/gethwrappers/generated/aggregator_v3_interface"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// TokenConfig armazena a configuração de cada token que desejamos monitorar.&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;TokenConfig&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Symbol&lt;/span&gt;  &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Address&lt;/span&gt; &lt;span class="n"&gt;common&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// FormattedPrice guarda o preço final e outras informações úteis.&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;FormattedPrice&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Symbol&lt;/span&gt;    &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Price&lt;/span&gt;     &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Float&lt;/span&gt;
    &lt;span class="n"&gt;Timestamp&lt;/span&gt; &lt;span class="kt"&gt;uint64&lt;/span&gt;
    &lt;span class="n"&gt;Decimals&lt;/span&gt;  &lt;span class="kt"&gt;uint8&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Conectando a um nó da Ethereum. Este endpoint público é ótimo para      começar.&lt;/span&gt;
    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ethclient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://ethereum-rpc.publicnode.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ops! Deu ruim ao conectar no Ethereum: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Nossa lista de alvos! Adicione quantos tokens quiser aqui.&lt;/span&gt;
    &lt;span class="c"&gt;// Esses endereços são endereços da MAINNET.&lt;/span&gt;
    &lt;span class="n"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;TokenConfig&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"ETH"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;common&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HexToAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419"&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"BTC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;common&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HexToAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c"&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"LINK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;common&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HexToAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0x2c1d072e956AFFC0D435Cb7AC38EF18d24d9127c"&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Este canal vai receber os preços assim que eles foremencontrados.&lt;/span&gt;
    &lt;span class="n"&gt;pricesChan&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="n"&gt;FormattedPrice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c"&gt;// Um contexto com timeout para não ficarmos presos esperando para   sempre. :p&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Lança uma "missão" para buscar o preço de cada token, tudo ao mesmo tempo.&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;fetchTokenPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pricesChan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Agora, a gente espera e coleta os resultados que chegam pelo canal.&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Buscando preços..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;pricesChan&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"✅ Preço do %s: %.2f USD (Atualizado em: %d)&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Demorou demais! O timeout foi atingido: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Err&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;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;fetchTokenPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ethclient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="n"&gt;TokenConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pricesChan&lt;/span&gt; &lt;span class="k"&gt;chan&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;FormattedPrice&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Cria uma instância do contrato para a gente poder interagir com ele.&lt;/span&gt;
    &lt;span class="n"&gt;aggregator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;aggregator_v3_interface&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewAggregatorV3Interface&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Erro ao instanciar o contrato para %s: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&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="c"&gt;// Pega os dados mais recentes do oráculo.&lt;/span&gt;
    &lt;span class="n"&gt;roundData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;aggregator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LatestRoundData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Erro ao buscar os dados para %s: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&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="c"&gt;// Descobre quantas casas decimais o preço tem.&lt;/span&gt;
    &lt;span class="n"&gt;decimals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;aggregator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Decimals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Erro ao buscar as casas decimais para %s: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&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="c"&gt;// O preço vem como um número inteiro gigante. A gente precisa formatá-lo.&lt;/span&gt;
    &lt;span class="n"&gt;priceFloat&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;roundData&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Answer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;divisor&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decimals&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;formattedPrice&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Quo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;priceFloat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;divisor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Envia o resultado bonitão de volta para a função main através do canal.&lt;/span&gt;
    &lt;span class="n"&gt;pricesChan&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;FormattedPrice&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Price&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;formattedPrice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;roundData&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UpdatedAt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Uint64&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;Decimals&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;decimals&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;h2&gt;
  
  
  5. Execução do Código
&lt;/h2&gt;

&lt;p&gt;Para compilar e executar a aplicação, basta utilizar nosso velho conhecido comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go run main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se tudo deu certo (tomara que sim 🙏), a  saída esperada será parecida com essa :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Buscando preços...
✅ Preço do ETH: 4170.75 USD (Atualizado em: 1758737807)
✅ Preço do LINK: 21.89 USD (Atualizado em: 1758739211)
✅ Preço do BTC: 113825.78 USD (Atualizado em: 1758736295)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚠️ Pontos de Atenção
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rede Certa, Endereço Certo&lt;/strong&gt;: Os endereços dos contratos mudam de uma rede para outra (Mainnet é diferente de Sepolia). Use sempre o endereço correto para a rede à qual você está conectado.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sem Custos de Gás&lt;/strong&gt;: Este código apenas lê dados da blockchain, o que é de &lt;strong&gt;graça&lt;/strong&gt; (ainda bem)! Operações de escrita, por outro lado, exigiriam uma carteira com fundos para pagar as taxas (gás).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Latência&lt;/strong&gt;: Os preços não são atualizados em tempo real, mas sim quando há uma variação mínima ou quando um período de tempo (o tal do &lt;em&gt;heartbeat&lt;/em&gt;) passa. Leve isso em conta!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Pronto! Agora você tem uma aplicação em Go eficiente para buscar preços de criptomoedas usando o poder da Chainlink. Esse é um exemplo simples mas com essa base, podemos criar projetos muito mais legais e complexos. &lt;br&gt;
Usamos concorrência para acelerar as coisas e garantimos que o programa não trave com timeouts.&lt;/p&gt;

&lt;p&gt;Para mais informações, a &lt;a href="https://docs.chain.link/" rel="noopener noreferrer"&gt;documentação oficial da Chainlink&lt;/a&gt; é sempre o melhor lugar para procurar.&lt;/p&gt;

&lt;p&gt;Agora, é com você. &lt;strong&gt;Just Code It!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>cryptocurrency</category>
      <category>blockchain</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Revisão Automática de PRs no GitHub com Gemini Code Assist</title>
      <dc:creator>Adriano P. Araujo</dc:creator>
      <pubDate>Wed, 17 Sep 2025 17:22:09 +0000</pubDate>
      <link>https://forem.com/dev-araujo/revisao-automatica-de-prs-no-github-com-gemini-code-assist-241n</link>
      <guid>https://forem.com/dev-araujo/revisao-automatica-de-prs-no-github-com-gemini-code-assist-241n</guid>
      <description>&lt;h2&gt;
  
  
  Chega de revisar código sozinho!
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F44tq9bp0njj6hol5zww8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F44tq9bp0njj6hol5zww8.gif" alt="Chega de revisar código sozinho!" width="480" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A gente sabe como é: revisão de código é vital, mas consome um tempo precioso que você poderia estar usando para codificar.&lt;/p&gt;

&lt;p&gt;A boa notícia? Dá para automatizar essa tarefa sem abrir a carteira. O Gemini Code Assist é um app gratuito para o GitHub que atua como um colega de equipe virtual. Ele mergulha nos seus Pull Requests, aponta o que pode ser melhorado e te dá sugestões práticas. É o fim daquela pilha de PRs esperando por uma revisão.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Botando as coisas para funcionar
&lt;/h2&gt;

&lt;p&gt;A instalação consiste nos seguintes passos:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fbivmxm3hwurxgnbgq1xn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fbivmxm3hwurxgnbgq1xn.png" alt="Instalando o gemini-code-assist" width="800" height="234"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Vá até o &lt;a href="https://github.com/marketplace/gemini-code-assist" rel="noopener noreferrer"&gt;Marketplace do GitHub&lt;/a&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; Clique em &lt;strong&gt;"Install"&lt;/strong&gt;(lá no fim da página) e autorize o acesso. Escolha em quais repositórios o robô vai fuçar (eu liberei todos os meus, mas aí escolha é sua).&lt;/li&gt;
&lt;li&gt; Aceite os Termos de Serviço do Google e pronto. O &lt;code&gt;gemini-code-assist[bot]&lt;/code&gt; já vai estar na área.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Deixando o robô com a sua cara&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para o Gemini não sair dando palpite genérico e perder tempo com arquivos que não interessam, crie uma pasta &lt;code&gt;.gemini/&lt;/code&gt; na raiz do seu projeto e ajuste as configurações. A pasta deve conter os dois arquivos :&lt;/p&gt;

&lt;p&gt;1.&lt;strong&gt;&lt;code&gt;styleguide.md&lt;/code&gt;:&lt;/strong&gt; Crie esse arquivo para &lt;strong&gt;ditar suas regras.&lt;/strong&gt; O que ele faz? Dita as regras, ora!  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo do &lt;code&gt;styleguide.md&lt;/code&gt;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Nossas Regras Sagradas&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Aqui usamos TypeScript. O tipo &lt;span class="sb"&gt;`any`&lt;/span&gt; é proibido e pode causar demissão (do PR).
&lt;span class="p"&gt;-&lt;/span&gt; Em React, componentes de função são lei.
&lt;span class="p"&gt;-&lt;/span&gt; Nada de "números mágicos" soltos no código. Crie constantes, pelo amor.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claro, esse é um style-guide é apenas um exemplo bem-humorado que você não deveria ver em produção(ou deveria?🤔). Você pode incluir coisas mais específicas, como princípios &lt;a href="https://pt.wikipedia.org/wiki/SOLID" rel="noopener noreferrer"&gt;SOLID&lt;/a&gt;, &lt;a href="https://medium.com/@rafaelcruz_48213/desenvolva-um-c%C3%B3digo-melhor-com-object-calisthenics-d5364767a9ba" rel="noopener noreferrer"&gt;Object Calisthenics&lt;/a&gt;, boas práticas da sua linguagem, etc.&lt;/p&gt;

&lt;p&gt;Ah já ia me esquecendo, o &lt;code&gt;styleguide.md&lt;/code&gt; dá o &lt;strong&gt;contexto&lt;/strong&gt; da interação do gemini com o seu código, por isso é legal deixar claro a &lt;em&gt;stack&lt;/em&gt; utilizada seja ela qual for, Go, Node, React, etc.&lt;/p&gt;

&lt;p&gt;2.&lt;strong&gt;&lt;code&gt;config.yaml&lt;/code&gt;:&lt;/strong&gt; Aqui você define o comportamento geral do bot, incluindo o que ele deve ignorar.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo do &lt;code&gt;config.yaml&lt;/code&gt; e o que cada propriedade significa :&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;have_fun&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;# Isso aqui não faz nada, só deixa o clima leve.Se você não curtir gracinhas só definir como false&lt;/span&gt;
&lt;span class="na"&gt;code_review&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Aqui você define à partir de que nível de severidade ele apontará as divergências do styleguide.md do seu código, no exemplo abaixo ele começa a apontar à partir de divergências de nível médio&lt;/span&gt;
  &lt;span class="na"&gt;comment_severity_threshold&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MEDIUM&lt;/span&gt; &lt;span class="c1"&gt;# Os níveis são LOW - MEDIUM - HIGH - CRITICAL&lt;/span&gt;
  &lt;span class="na"&gt;max_review_comments&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;  &lt;span class="c1"&gt;# O limite de comentários por review&lt;/span&gt;
  &lt;span class="c1"&gt;# Lista de arquivos e pastas que o Gemini deve ignorar na revisão. Funciona como um .gitignore&lt;/span&gt;
  &lt;span class="na"&gt;ignore_patterns&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;frontend/node_modules/**&lt;/span&gt; 
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;frontend/dist/**&lt;/span&gt; 
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;frontend/**/*.spec.ts&lt;/span&gt;     
  &lt;span class="na"&gt;pull_request_opened&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
    &lt;span class="na"&gt;summary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;  &lt;span class="c1"&gt;# Se você quiser um resumo das alterações implementadas quando o PR for aberto, vote true&lt;/span&gt;
    &lt;span class="na"&gt;code_review&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;# Para reforçar de que você deseja que ele faça a revisão de código&lt;/span&gt;

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  2. A mágica acontecendo
&lt;/h2&gt;

&lt;p&gt;Assim que um PR é aberto, o Gemini entra em ação. Em cerca de 5 minutos, ele aparece com:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Resumo do PR:&lt;/strong&gt; Uma sinopse das mudanças, ideal pra quem tá com preguiça de ler tudo e perfeito para documentações.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Análise do Código:&lt;/strong&gt; Comentários &lt;em&gt;inline&lt;/em&gt; nas linhas que ele acha que podem melhorar. Ele classifica a gravidade (de &lt;code&gt;LOW&lt;/code&gt; a &lt;code&gt;CRITICAL&lt;/code&gt;), explica o motivo e, muitas vezes, já dá a sugestão de correção pronta pra aplicar.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Precisando de uma ajudinha extra?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use os comandos &lt;strong&gt;diretamente nos comentários&lt;/strong&gt;(isso é muito maneiro), do PR para chamar o bot:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Comando&lt;/th&gt;
&lt;th&gt;O que faz&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/gemini review&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;“Ô, robô! Dá uma olhada de novo aqui, por favor.”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/gemini summary&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;“Me perdi. Faz um resumo desse PR de novo.”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@gemini-code-assist&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Permite fazer uma pergunta específica sobre um trecho de código.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/gemini help&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;“Socorro! Quais são os comandos mesmo?”&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  3. Pontos positivos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Economia de tempo:&lt;/strong&gt; Você foca em codar; ele foca em revisar. Prático.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistência no código:&lt;/strong&gt; Chega de cada um fazer do seu jeito. O robô vira o fiscal do padrão, e garante a qualidade do código segundo os padrões definidos pelo time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aprendizado acelerado:&lt;/strong&gt; Por essa aqui provavelmente você não esperava, para mim, tem sido uma ferramenta de estudo: &lt;strong&gt;tô aprofundando em Go e uso as correções que o Gemini sugere para melhorar e perceber onde estou falhando&lt;/strong&gt;. Ele aponta erros, sugere formas mais idiomáticas e me faz entender o &lt;em&gt;porquê&lt;/em&gt; daquela sugestão. É como ter um professor particular de código. Esse código &lt;a href="https://github.com/dev-araujo/chainlink-price-feed" rel="noopener noreferrer"&gt;aqui&lt;/a&gt; escrito em Go teve todos os seus PRs revisados pelo Gemini 😲&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. Nem tudo são flores
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fsmux8784d3nu48wd67x9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fsmux8784d3nu48wd67x9.gif" alt="pc fire" width="444" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Não é perfeito:&lt;/strong&gt; Como está em &lt;em&gt;preview&lt;/em&gt;, às vezes ele pode dar uma sugestão meio sem noção. Então assim, nada de confiar cegamente na IA.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Suporte a linguagens:&lt;/strong&gt; Confere se ele entende a linguagem ou stack do seu projeto.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conectividade:&lt;/strong&gt; Não rola em organizações do GitHub com restrições de rede muito específicas.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5. Alguns conselhos
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Use como primeiro filtro:&lt;/strong&gt; Deixe o Gemini pegar os problemas óbvios. Para a lógica de negócio que pode quebrar tudo, &lt;strong&gt;chame um humano&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Comece com calma:&lt;/strong&gt; Use &lt;code&gt;comment_severity_threshold: MEDIUM&lt;/code&gt; pra não ser soterrado de notificações logo de cara.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Dê feedback pro robô:&lt;/strong&gt; Use os emojis 👍 e 👎 nos comentários dele. Isso ajuda a IA a aprender.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Capriche no &lt;code&gt;styleguide.md&lt;/code&gt;:&lt;/strong&gt; Quanto mais claras suas regras, mais certeiras serão as revisões. &lt;strong&gt;Dica de ouro:&lt;/strong&gt; quer que os resumos e sugestões venham em português? Escreva o &lt;code&gt;styleguide.md&lt;/code&gt; em português. O mesmo vale para qualquer outro idioma.&lt;/li&gt;
&lt;/ol&gt;




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

&lt;p&gt;A moral da história é simples: o Gemini Code Assist é aquele parceiro de código que faltava, seja para turbinar seu aprendizado solo ou para ajudar sua equipe a manter o padrão de qualidade sem dor de cabeça.&lt;/p&gt;

&lt;p&gt;Ele automatiza a parte chata, te ensina a programar melhor e mantém seu projeto nos trilhos.&lt;/p&gt;

&lt;p&gt;Instale, teste e deixe o robô trabalhar. Vale a pena a experiência.&lt;/p&gt;

&lt;p&gt;Se você chegou até aqui, eu espero enormemente que esse artigo tenha sido útil para você de alguma maneira.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Just Code it!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>gemini</category>
      <category>ai</category>
      <category>automation</category>
      <category>github</category>
    </item>
  </channel>
</rss>
