<?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: Danilo Itagyba</title>
    <description>The latest articles on Forem by Danilo Itagyba (@itagyba).</description>
    <link>https://forem.com/itagyba</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%2F357537%2F6dd3b8b3-d89e-42fb-aee7-4f2dec30ddcd.png</url>
      <title>Forem: Danilo Itagyba</title>
      <link>https://forem.com/itagyba</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/itagyba"/>
    <language>en</language>
    <item>
      <title>Codex CLI no dia a dia: como usar IA no terminal com boas práticas</title>
      <dc:creator>Danilo Itagyba</dc:creator>
      <pubDate>Mon, 13 Apr 2026 17:30:40 +0000</pubDate>
      <link>https://forem.com/itagyba/codex-cli-no-dia-a-dia-como-usar-ia-no-terminal-com-boas-praticas-2iln</link>
      <guid>https://forem.com/itagyba/codex-cli-no-dia-a-dia-como-usar-ia-no-terminal-com-boas-praticas-2iln</guid>
      <description>&lt;p&gt;O &lt;strong&gt;Codex CLI&lt;/strong&gt; mudou a forma como escrevemos código: ao invés de digitar linha por linha, passamos a &lt;strong&gt;orquestrar tarefas&lt;/strong&gt; usando IA diretamente no terminal.&lt;/p&gt;

&lt;p&gt;Mas tem um detalhe importante:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 Usar IA sem boas práticas pode gerar mais problemas do que soluções.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Neste artigo você vai ver:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Como usar o Codex CLI no dia a dia&lt;/li&gt;
&lt;li&gt;Boas práticas reais (baseadas no guia oficial)&lt;/li&gt;
&lt;li&gt;E principalmente: &lt;strong&gt;por que testes são ainda mais importantes com IA&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 O que é o Codex CLI?
&lt;/h2&gt;

&lt;p&gt;O Codex CLI é um agente de desenvolvimento que roda no terminal e permite:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gerar código com contexto do projeto&lt;/li&gt;
&lt;li&gt;Refatorar código existente&lt;/li&gt;
&lt;li&gt;Criar testes automaticamente&lt;/li&gt;
&lt;li&gt;Automatizar tarefas (CI/CD, scripts, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ele funciona como um &lt;strong&gt;pair programmer que executa código por você&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Setup básico
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @openai/codex
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-api-key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex &lt;span class="s2"&gt;"Create a REST API with validation and pagination"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧠 Como pensar ao usar Codex
&lt;/h2&gt;

&lt;p&gt;Mude sua mentalidade:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;❌ Antes: eu escrevo código&lt;br&gt;
✅ Agora: eu descrevo o problema e reviso a solução&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fluxo ideal:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Você define o problema&lt;/li&gt;
&lt;li&gt;Codex gera a solução&lt;/li&gt;
&lt;li&gt;Você revisa&lt;/li&gt;
&lt;li&gt;Você valida (testes!)&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🧩 Boas práticas essenciais
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Dê contexto (isso muda tudo)
&lt;/h3&gt;

&lt;p&gt;❌ Ruim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex &lt;span class="s2"&gt;"fix bug"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Bom:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex &lt;span class="s2"&gt;"Fix null reference in UserService when email is missing. Add validation and unit tests."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  2. Quebre tarefas grandes
&lt;/h3&gt;

&lt;p&gt;❌ Evite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex &lt;span class="s2"&gt;"Build entire system"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Prefira:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex &lt;span class="s2"&gt;"Create authentication service"&lt;/span&gt;
codex &lt;span class="s2"&gt;"Add JWT support"&lt;/span&gt;
codex &lt;span class="s2"&gt;"Write unit tests"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  3. Planeje antes de executar
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex &lt;span class="s2"&gt;"Plan how to migrate this monolith to microservices"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depois:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex &lt;span class="s2"&gt;"Implement step 1 of the plan"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  4. Use AGENTS.md
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# AGENTS.md&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Use clean architecture
&lt;span class="p"&gt;-&lt;/span&gt; Prefer repository pattern
&lt;span class="p"&gt;-&lt;/span&gt; Use xUnit for tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Isso padroniza o comportamento do Codex no projeto&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Use intenção, não sintaxe
&lt;/h3&gt;

&lt;p&gt;❌&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex &lt;span class="s2"&gt;"write a for loop in C#"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex &lt;span class="s2"&gt;"Iterate over active users and filter inactive ones"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  6. Trabalhe em ciclos curtos
&lt;/h3&gt;

&lt;p&gt;Pequenas mudanças = menos bugs + mais controle&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 A parte mais importante: TESTES
&lt;/h2&gt;

&lt;p&gt;Se você só lembrar de uma coisa desse artigo, que seja isso:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;❗ Código gerado por IA sem testes é um risco real&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A IA gera código que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Parece correto&lt;/li&gt;
&lt;li&gt;Compila&lt;/li&gt;
&lt;li&gt;Mas pode estar errado&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 Regra de ouro
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 Se não tem teste, não existe&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧩 Tipos de testes que você DEVE usar
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✔️ Unit Test
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Should_Return_Error_When_Email_Is_Invalid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"invalid-email"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;False&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Success&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;
  
  
  ✔️ Integration Test
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;Should_Create_User_In_Database&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&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;_factory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;PostAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/users"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpStatusCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Created&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusCode&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;
  
  
  ✔️ Regression Test
&lt;/h3&gt;

&lt;p&gt;Sempre rode após usar IA:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚠️ O que acontece se você NÃO testar
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Bugs silenciosos em produção&lt;/li&gt;
&lt;li&gt;Regressões inesperadas&lt;/li&gt;
&lt;li&gt;Falhas de segurança&lt;/li&gt;
&lt;li&gt;Performance ruim&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Quanto mais IA você usa, mais testes você precisa&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Boas práticas com testes + Codex
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✔️ Gere testes junto com código
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex &lt;span class="s2"&gt;"Create order service with unit tests"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  ✔️ Crie testes antes de refatorar
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex &lt;span class="s2"&gt;"Write unit tests for this class before refactoring"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Técnica: &lt;em&gt;test safety net&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  ✔️ Aumente cobertura automaticamente
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex &lt;span class="s2"&gt;"Increase test coverage and include edge cases"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  ✔️ Automatize no CI/CD
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Test&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run tests&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dotnet test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧱 Exemplos reais de uso
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Criar endpoint
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex &lt;span class="s2"&gt;"Create a .NET API endpoint with validation and error handling"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Otimizar SQL
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex &lt;span class="s2"&gt;"Optimize this SQL query and suggest indexes"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Refatorar código
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex &lt;span class="s2"&gt;"Refactor this service to use dependency injection"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚠️ Erros comuns
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Erro&lt;/th&gt;
&lt;th&gt;Problema&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Prompt genérico&lt;/td&gt;
&lt;td&gt;Resultado ruim&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tarefa grande demais&lt;/td&gt;
&lt;td&gt;Código inconsistente&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sem revisão&lt;/td&gt;
&lt;td&gt;Bugs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sem contexto&lt;/td&gt;
&lt;td&gt;IA “chuta”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sem testes&lt;/td&gt;
&lt;td&gt;💥 produção&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




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

&lt;p&gt;O Codex CLI muda completamente o jogo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Você deixa de escrever código&lt;/li&gt;
&lt;li&gt;E passa a &lt;strong&gt;orquestrar código&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mas o sucesso depende disso:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 Contexto + Iteração + Testes + Revisão&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  📌 TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Dê contexto claro&lt;/li&gt;
&lt;li&gt;Trabalhe em etapas&lt;/li&gt;
&lt;li&gt;Planeje tarefas grandes&lt;/li&gt;
&lt;li&gt;Use AGENTS.md&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Teste tudo que a IA gerar&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Revise sempre&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>ai</category>
      <category>productivity</category>
      <category>dotnet</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Blindando Aplicações no .NET 10: Um Guia Completo sobre Polly e Resiliência</title>
      <dc:creator>Danilo Itagyba</dc:creator>
      <pubDate>Mon, 09 Feb 2026 14:29:15 +0000</pubDate>
      <link>https://forem.com/itagyba/blindando-aplicacoes-no-net-10-um-guia-completo-sobre-polly-e-resiliencia-4d5a</link>
      <guid>https://forem.com/itagyba/blindando-aplicacoes-no-net-10-um-guia-completo-sobre-polly-e-resiliencia-4d5a</guid>
      <description>&lt;h1&gt;
  
  
  Resiliência à Prova de Falhas no .NET 10 com Polly
&lt;/h1&gt;

&lt;p&gt;No desenvolvimento de software moderno, especialmente em arquiteturas de microsserviços e nuvem, a estabilidade não é definida pela ausência de falhas, mas pela capacidade do sistema de &lt;strong&gt;resistir e se recuperar&lt;/strong&gt; delas.&lt;/p&gt;

&lt;p&gt;Com a chegada do &lt;strong&gt;.NET 10&lt;/strong&gt; (e seguindo a evolução desde o .NET 8), a forma de implementar resiliência mudou drasticamente. As antigas &lt;code&gt;Policies&lt;/code&gt; síncronas e pesadas deram lugar aos &lt;strong&gt;Resilience Pipelines&lt;/strong&gt;: leves, performáticos e nativos para código assíncrono.&lt;/p&gt;

&lt;p&gt;Este artigo explora como utilizar o poder do Polly em conjunto com o &lt;code&gt;Microsoft.Extensions.Http.Resilience&lt;/code&gt; para criar aplicações robustas.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. O Novo Paradigma: Resilience Pipelines
&lt;/h2&gt;

&lt;p&gt;Diferente das versões anteriores do Polly (v7 e inferiores), a nova arquitetura (v8+) foca em:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero-Allocation (ou quase):&lt;/strong&gt; Redução drástica no consumo de memória.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pipeline Pattern:&lt;/strong&gt; Estratégias são encadeadas de forma lógica e fluente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integração Nativa:&lt;/strong&gt; Telemetria, Logging e Injeção de Dependência já "saem da caixa".&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Instalação
&lt;/h3&gt;

&lt;p&gt;Para projetos .NET modernos, você deve instalar os seguintes pacotes via NuGet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package Polly.Core
dotnet add package Microsoft.Extensions.Http.Resilience

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

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; O pacote &lt;code&gt;Microsoft.Extensions.Http.Resilience&lt;/code&gt; é a recomendação oficial da Microsoft para aplicações web e APIs.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  2. Estratégias Fundamentais de Resiliência
&lt;/h2&gt;

&lt;p&gt;Abaixo, detalhamos as principais estratégias (strategies) utilizando a sintaxe moderna do &lt;code&gt;ResiliencePipelineBuilder&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  A. Retry (Tentativa) com Jitter
&lt;/h3&gt;

&lt;p&gt;A estratégia mais básica. Se falhar, tente novamente. No entanto, o &lt;strong&gt;Retry&lt;/strong&gt; simples é perigoso (pode causar efeito "Thundering Herd"). A solução é o &lt;strong&gt;Backoff Exponencial com Jitter&lt;/strong&gt; (ruído aleatório), que agora é o padrão no Polly moderno.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Polly&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Polly.Retry&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;ResiliencePipeline&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ResiliencePipelineBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddRetry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;RetryStrategyOptions&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Trata exceções de rede e códigos 5xx&lt;/span&gt;
        &lt;span class="n"&gt;ShouldHandle&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PredicateBuilder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;HttpRequestException&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;MaxRetryAttempts&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="n"&gt;Delay&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;BackoffType&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DelayBackoffType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exponential&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Inclui Jitter automaticamente&lt;/span&gt;
        &lt;span class="n"&gt;OnRetry&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Tentativa &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AttemptNumber&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; falhou. Retentando..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ValueTask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CompletedTask&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="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  B. Circuit Breaker (Disjuntor)
&lt;/h3&gt;

&lt;p&gt;Protege o sistema de destino. Se um serviço está fora do ar, continuar tentando só piora a situação. O Circuit Breaker "abre o circuito" após um número de falhas, falhando imediatamente novas requisições para dar tempo ao serviço de se recuperar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;circuitOptions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;CircuitBreakerStrategyOptions&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;FailureRatio&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="c1"&gt;// Se 50% das requisições falharem...&lt;/span&gt;
    &lt;span class="n"&gt;SamplingDuration&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// ...nos últimos 30s...&lt;/span&gt;
    &lt;span class="n"&gt;MinimumThroughput&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// ...com no mínimo 7 requisições...&lt;/span&gt;
    &lt;span class="n"&gt;BreakDuration&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="c1"&gt;// ...abra o circuito por 1 min.&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ResiliencePipelineBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddCircuitBreaker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;circuitOptions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  C. Fallback (Plano de Contingência)
&lt;/h3&gt;

&lt;p&gt;Quando tudo falha (Retry esgotado, Circuito aberto), o Fallback define o que fazer para não estourar erro na cara do usuário. Pode ser retornar um dado do cache ou um valor padrão.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ResiliencePipelineBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddFallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;FallbackStrategyOptions&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UserDto&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;FallbackAction&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Outcome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;UserDto&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Usuário Padrão"&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
        &lt;span class="n"&gt;OnFallback&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; 
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Fallback acionado! Retornando dados provisórios."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ValueTask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CompletedTask&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="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  D. Hedging (Especulação)
&lt;/h3&gt;

&lt;p&gt;Útil para baixa latência. O Hedging dispara requisições paralelas (ou com pequeno atraso). A primeira que retornar com sucesso é usada; as outras são canceladas.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Exemplo:&lt;/em&gt; Você chama uma API que às vezes demora 5s, mas normalmente leva 100ms. O Hedging dispara uma segunda chamada se a primeira demorar mais que 200ms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ResiliencePipelineBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddHedging&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;HedgingStrategyOptions&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;MaxHedgedAttempts&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Delay&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromMilliseconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;500&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// Dispara 2ª tentativa se 1ª demorar 500ms&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. A Implementação "Gold Standard" no .NET 10
&lt;/h2&gt;

&lt;p&gt;Em aplicações reais (.NET Core API, Worker Services, Blazor), você raramente constrói pipelines manualmente. Você utiliza a &lt;strong&gt;Injeção de Dependência&lt;/strong&gt; para decorar o &lt;code&gt;HttpClient&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A Microsoft introduziu o &lt;code&gt;AddStandardResilienceHandler&lt;/code&gt;, que aplica uma combinação pré-configurada e otimizada de:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Rate Limiter&lt;/li&gt;
&lt;li&gt;Total Timeout&lt;/li&gt;
&lt;li&gt;Retry&lt;/li&gt;
&lt;li&gt;Circuit Breaker&lt;/li&gt;
&lt;li&gt;Attempt Timeout&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Configuração no &lt;code&gt;Program.cs&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.DependencyInjection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.Hosting&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateApplicationBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// 1. Registro do HttpClient nomeado&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddHttpClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CatalogoApi"&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;=&amp;gt;&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;BaseAddress&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://api.catalogo.com"&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;Timeout&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Timeout do socket&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;// 2. Adicionando a Resiliência Padrão&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddStandardResilienceHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Podemos customizar os padrões se necessário&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Retry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaxRetryAttempts&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CircuitBreaker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BreakDuration&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;15&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TotalRequestTimeout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timeout&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Consumindo o Serviço Resiliente
&lt;/h3&gt;

&lt;p&gt;Sua classe de serviço não precisa saber que o Polly existe. A resiliência é transparente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CatalogoService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IHttpClientFactory&lt;/span&gt; &lt;span class="n"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CatalogoService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;HttpClient&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;factory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CatalogoApi"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Produto&lt;/span&gt;&lt;span class="p"&gt;?&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetProdutoAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Se a rede falhar, o Polly intercepta, tenta de novo, &lt;/span&gt;
        &lt;span class="c1"&gt;// ou abre o circuito automaticamente aqui.&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; 
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&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;GetFromJsonAsync&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Produto&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;$"/produtos/&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="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Logar apenas se todas as estratégias de resiliência falharem&lt;/span&gt;
            &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Não foi possível obter o produto após múltiplas tentativas."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;throw&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;h2&gt;
  
  
  4. Cenários Avançados: Pipeline Registry
&lt;/h2&gt;

&lt;p&gt;Às vezes, você precisa reutilizar a mesma estratégia de resiliência em vários lugares que não são necessariamente chamadas HTTP (ex: acesso a arquivos, conexões Redis). Para isso, usamos o &lt;code&gt;ResiliencePipelineProvider&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Registro
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddResiliencePipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"meu-pipeline-banco"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddRetry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;RetryStrategyOptions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;MaxRetryAttempts&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&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;
  
  
  Uso Injetado
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BancoService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ResiliencePipelineProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pipelineProvider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;SalvarDadosAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;dados&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Recupera o pipeline pelo nome&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pipelineProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetPipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"meu-pipeline-banco"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Executa qualquer código arbitrário com resiliência&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExecuteAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; 
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExecuteCommandAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dados&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="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;ct&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. Checklist de Melhores Práticas
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Idempotência é Chave:&lt;/strong&gt; Nunca use &lt;em&gt;Retry&lt;/em&gt; em métodos que não sejam idempotentes (ex: &lt;code&gt;POST&lt;/code&gt; para criar pedido) a menos que sua API suporte verificação de duplicidade. Se a primeira requisição criou o pedido mas a resposta falhou na rede, o Retry pode criar um pedido duplicado.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Timeouts em Camadas:&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Attempt Timeout:&lt;/em&gt; Tempo para cada tentativa individual (curto).&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Total Timeout:&lt;/em&gt; Tempo máximo para todo o processo (longo).&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Socket Timeout:&lt;/em&gt; Configuração do &lt;code&gt;HttpClient&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Circuit Breaker Distribuído:&lt;/strong&gt; Lembre-se que o Circuit Breaker é &lt;strong&gt;local&lt;/strong&gt; (na memória da instância). Se você tem 10 réplicas da sua API no Kubernetes, cada uma terá seu próprio estado de circuito.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Não trate tudo:&lt;/strong&gt; Não use Retry para erros de negócio (&lt;code&gt;400 Bad Request&lt;/code&gt;, &lt;code&gt;403 Forbidden&lt;/code&gt;). Resiliência é para falhas transitórias (&lt;code&gt;503 Service Unavailable&lt;/code&gt;, &lt;code&gt;408 Request Timeout&lt;/code&gt;, falhas de rede).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;No .NET 10, a biblioteca Polly deixou de ser apenas um utilitário de terceiros para se tornar parte integrante da stack de rede da Microsoft. Ao utilizar &lt;code&gt;Microsoft.Extensions.Http.Resilience&lt;/code&gt; e os novos Pipelines, você garante que sua aplicação seja capaz de suportar as instabilidades inerentes à nuvem com performance máxima e código limpo.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>microservices</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>🚀 Node.js Best Practices</title>
      <dc:creator>Danilo Itagyba</dc:creator>
      <pubDate>Fri, 05 Dec 2025 14:27:43 +0000</pubDate>
      <link>https://forem.com/itagyba/nodejs-best-practices-cursor-rules-1pa5</link>
      <guid>https://forem.com/itagyba/nodejs-best-practices-cursor-rules-1pa5</guid>
      <description>&lt;h1&gt;
  
  
  Node.js Best Practices
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Comprehensive Node.js development guidelines &lt;br&gt;
Based on &lt;a href="https://github.com/goldbergyoni/nodebestpractices" rel="noopener noreferrer"&gt;goldbergyoni/nodebestpractices&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🎯 102 Best Practices | 📦 Node.js 22+ | &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Project Structure&lt;/li&gt;
&lt;li&gt;Framework Selection&lt;/li&gt;
&lt;li&gt;TypeScript Usage&lt;/li&gt;
&lt;li&gt;Error Handling&lt;/li&gt;
&lt;li&gt;Code Style and Patterns&lt;/li&gt;
&lt;li&gt;Testing and Quality&lt;/li&gt;
&lt;li&gt;Production Best Practices&lt;/li&gt;
&lt;li&gt;Security Best Practices&lt;/li&gt;
&lt;li&gt;Docker Best Practices&lt;/li&gt;
&lt;li&gt;Code Examples&lt;/li&gt;
&lt;li&gt;Summary Checklist&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;

&lt;h3&gt;
  
  
  📂 Component-Based Architecture
&lt;/h3&gt;

&lt;p&gt;Structure your application by business components (bounded contexts) for better modularity and maintainability.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-system/
├── apps/                    # Business components
│   ├── orders/
│   ├── users/
│   ├── payments/
└── libraries/               # Shared utilities
    ├── logger/
    └── authenticator/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Reduced mental overload&lt;/li&gt;
&lt;li&gt;✅ Smaller, granular changes&lt;/li&gt;
&lt;li&gt;✅ Faster development cycles&lt;/li&gt;
&lt;li&gt;✅ Clear modularity borders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Anti-pattern:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ Mixing artifacts from different modules&lt;/li&gt;
&lt;li&gt;❌ Tightly-coupled 'spaghetti' architecture&lt;/li&gt;
&lt;li&gt;❌ Global dependencies everywhere&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Best Practices:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Each module has its own &lt;code&gt;package.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;✅ Use &lt;code&gt;package.json.main&lt;/code&gt; or &lt;code&gt;package.json.exports&lt;/code&gt; for public API&lt;/li&gt;
&lt;li&gt;✅ Hide internal implementation details&lt;/li&gt;
&lt;li&gt;✅ Support Monorepo or multi-repo approaches&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  ⚙️ Configuration Management
&lt;/h3&gt;

&lt;p&gt;Implement secure, flexible configuration from day one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requirements:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Read from files AND environment variables&lt;/li&gt;
&lt;li&gt;✅ Keep secrets outside committed code&lt;/li&gt;
&lt;li&gt;✅ Hierarchical structure for easy navigation&lt;/li&gt;
&lt;li&gt;✅ Type support and validation&lt;/li&gt;
&lt;li&gt;✅ Default values for all keys&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Recommended Libraries:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/convict" rel="noopener noreferrer"&gt;convict&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/evanshortiss/env-var" rel="noopener noreferrer"&gt;env-var&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/colinhacks/zod" rel="noopener noreferrer"&gt;zod&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Example with convict&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;convict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;convict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;convict&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;development&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;development&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;NODE_ENV&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;port&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PORT&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="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;allowed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;strict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Framework Selection
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Recommended Frameworks (2024)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Nest.js&lt;/strong&gt; - For OOP teams and large-scale apps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fastify&lt;/strong&gt; - For microservices with simple Node.js mechanics&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Express&lt;/strong&gt; - For simplicity and wide ecosystem&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Koa&lt;/strong&gt; - For minimalist, modern middleware approach&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Framework Considerations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Evaluate based on team size, project scale, and architecture&lt;/li&gt;
&lt;li&gt;Consider TypeScript support and plugin ecosystem&lt;/li&gt;
&lt;li&gt;Assess performance requirements vs development speed&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  TypeScript Usage
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use TypeScript Sparingly and Thoughtfully
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Define variables and function return types&lt;/li&gt;
&lt;li&gt;Avoid over-engineering with advanced features&lt;/li&gt;
&lt;li&gt;Use ~50 keywords thoughtfully, not excessively&lt;/li&gt;
&lt;li&gt;Utilize advanced features only when truly needed&lt;/li&gt;
&lt;li&gt;Remember: Types catch ~20% of bugs; tests catch the rest&lt;/li&gt;
&lt;li&gt;Balance type safety with code simplicity&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Error Handling
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Async Error Handling
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use async-await or promises exclusively&lt;/li&gt;
&lt;li&gt;Avoid callback-style error handling (callback hell)&lt;/li&gt;
&lt;li&gt;Enable better error handling with try-catch blocks&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Error Object Standards
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Always extend the built-in Error object&lt;/li&gt;
&lt;li&gt;Add useful properties: name, code, isCatastrophic&lt;/li&gt;
&lt;li&gt;Use ESLint rule: &lt;code&gt;no-throw-literal&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;For TypeScript: &lt;code&gt;@typescript-eslint/no-throw-literal&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Error Classification
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Operational Errors&lt;/strong&gt;: Known, expected errors (invalid input)

&lt;ul&gt;
&lt;li&gt;Handle gracefully, log, and continue&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Catastrophic Errors&lt;/strong&gt;: Unknown programmer errors

&lt;ul&gt;
&lt;li&gt;Log, alert, and restart process gracefully&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Centralized Error Handling
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create dedicated error handler object&lt;/li&gt;
&lt;li&gt;Don't handle errors within middleware&lt;/li&gt;
&lt;li&gt;Encapsulate: logging, crash decisions, monitoring&lt;/li&gt;
&lt;li&gt;All entry points should use the same handler&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Error Documentation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Document API errors using OpenAPI or GraphQL&lt;/li&gt;
&lt;li&gt;Help API callers handle errors properly&lt;/li&gt;
&lt;li&gt;Prevent unexpected crashes in client applications&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Process Exit Strategy
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Exit gracefully on unknown errors&lt;/li&gt;
&lt;li&gt;Let runtime (Docker, Kubernetes) restart the process&lt;/li&gt;
&lt;li&gt;Log observable errors before shutdown&lt;/li&gt;
&lt;li&gt;Close connections properly&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Logging Best Practices
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use mature logger: Pino or Winston (avoid console.log)&lt;/li&gt;
&lt;li&gt;Support log levels, pretty printing, and coloring&lt;/li&gt;
&lt;li&gt;Write logs to stdout (let infrastructure handle routing)&lt;/li&gt;
&lt;li&gt;Attach custom properties with minimal serialization penalty&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing Error Flows
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Test both positive and error scenarios&lt;/li&gt;
&lt;li&gt;Simulate uncaught exceptions&lt;/li&gt;
&lt;li&gt;Verify error handler behavior&lt;/li&gt;
&lt;li&gt;Test error recovery mechanisms&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Monitoring
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use APM products to discover errors automatically&lt;/li&gt;
&lt;li&gt;Monitor performance and downtime proactively&lt;/li&gt;
&lt;li&gt;Gauge application health in real-time&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Promise Management
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Catch unhandled promise rejections&lt;/li&gt;
&lt;li&gt;Register to &lt;code&gt;process.unhandledRejection&lt;/code&gt; event&lt;/li&gt;
&lt;li&gt;Always await promises before returning for full stacktrace&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;return await&lt;/code&gt; pattern in async functions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Input Validation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Fail fast: validate arguments immediately&lt;/li&gt;
&lt;li&gt;Use validation libraries: ajv, zod, typebox&lt;/li&gt;
&lt;li&gt;Validate at API boundaries&lt;/li&gt;
&lt;li&gt;Assert API input to prevent nasty bugs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Event Emitter Error Handling
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Subscribe to 'error' events on event emitters&lt;/li&gt;
&lt;li&gt;Handle stream errors explicitly&lt;/li&gt;
&lt;li&gt;For EventTargets, use global process error handling&lt;/li&gt;
&lt;li&gt;Initialize emitters with &lt;code&gt;{captureRejections: true}&lt;/code&gt; for async handlers&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Code Style and Patterns
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ESLint Configuration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use ESLint as the standard linter&lt;/li&gt;
&lt;li&gt;Combine with Prettier for code formatting&lt;/li&gt;
&lt;li&gt;Catch errors and anti-patterns early&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Node.js-Specific Linting
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use plugins:

&lt;ul&gt;
&lt;li&gt;eslint-plugin-node&lt;/li&gt;
&lt;li&gt;eslint-plugin-security&lt;/li&gt;
&lt;li&gt;eslint-plugin-mocha / eslint-plugin-jest&lt;/li&gt;
&lt;li&gt;eslint-plugin-require&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Detect Node.js-specific anti-patterns&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Code Formatting Rules
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Opening braces on same line as statement&lt;/li&gt;
&lt;li&gt;Proper statement separation (use semicolons or understand ASI)&lt;/li&gt;
&lt;li&gt;Use ESLint semi rule&lt;/li&gt;
&lt;li&gt;Use no-unexpected-multiline rule&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Naming Conventions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;lowerCamelCase&lt;/strong&gt;: variables, constants, functions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UpperCamelCase&lt;/strong&gt;: classes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UPPER_SNAKE_CASE&lt;/strong&gt;: global/static variables&lt;/li&gt;
&lt;li&gt;Name all functions (avoid anonymous functions)&lt;/li&gt;
&lt;li&gt;Use descriptive but concise names&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Variable Declaration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Prefer &lt;code&gt;const&lt;/code&gt; over &lt;code&gt;let&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Avoid &lt;code&gt;var&lt;/code&gt; completely (ES6+)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;const&lt;/code&gt; prevents accidental reassignment&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;let&lt;/code&gt; for block-scoped variables that need reassignment&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Module Management
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Require modules at file beginning&lt;/li&gt;
&lt;li&gt;Import before any function definitions&lt;/li&gt;
&lt;li&gt;Avoid requires inside functions (except lazy loading)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Module Entry Points
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Set explicit entry point (index.js or package.json.main)&lt;/li&gt;
&lt;li&gt;Use package.json.exports for ESM&lt;/li&gt;
&lt;li&gt;Hide internal structure from clients&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Comparison Operators
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use strict equality &lt;code&gt;===&lt;/code&gt; over &lt;code&gt;==&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Avoid type coercion surprises&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Async Patterns
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use async-await as primary pattern&lt;/li&gt;
&lt;li&gt;Avoid callbacks (callback hell)&lt;/li&gt;
&lt;li&gt;Promises for library compatibility&lt;/li&gt;
&lt;li&gt;Arrow functions for compact code&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Side Effects
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Avoid effects outside of functions&lt;/li&gt;
&lt;li&gt;No DB/network calls at module load time&lt;/li&gt;
&lt;li&gt;Use factory or revealing module patterns for initialization&lt;/li&gt;
&lt;li&gt;Keep code testable and mockable&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Testing and Quality
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Test Coverage Requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Write API (component) tests at minimum&lt;/li&gt;
&lt;li&gt;Component tests provide more coverage than unit tests&lt;/li&gt;
&lt;li&gt;Use tools like Postman for API testing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Test Naming Convention (3 Parts)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;What is being tested (unit under test)&lt;/li&gt;
&lt;li&gt;Under what circumstances&lt;/li&gt;
&lt;li&gt;What is the expected result&lt;/li&gt;
&lt;li&gt;Example: "ProductService - when no price provided - should return validation error"&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Test Structure (AAA Pattern)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Arrange&lt;/strong&gt;: Setup test data and conditions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Act&lt;/strong&gt;: Execute the unit under test&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assert&lt;/strong&gt;: Verify expected outcome&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Environment Consistency
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use Node version management: nvm or Volta&lt;/li&gt;
&lt;li&gt;Specify Node version in project files&lt;/li&gt;
&lt;li&gt;Replicate to CI and production runtime&lt;/li&gt;
&lt;li&gt;Prevent version drift across environments&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Test Data Management
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Avoid global test fixtures and seeds&lt;/li&gt;
&lt;li&gt;Add data per-test (test isolation)&lt;/li&gt;
&lt;li&gt;Each test manages its own database state&lt;/li&gt;
&lt;li&gt;Prevent test coupling and interference&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Test Organization
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Tag tests by category: #cold, #api, #sanity, #integration&lt;/li&gt;
&lt;li&gt;Run subsets based on context (commit, PR, deploy)&lt;/li&gt;
&lt;li&gt;Example: &lt;code&gt;mocha --grep 'sanity'&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Code Coverage
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use Istanbul/NYC for coverage reports&lt;/li&gt;
&lt;li&gt;Identify untested code paths&lt;/li&gt;
&lt;li&gt;Set coverage thresholds in CI&lt;/li&gt;
&lt;li&gt;Fail builds on coverage decrease&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  E2E Testing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use production-like environment&lt;/li&gt;
&lt;li&gt;Leverage docker-compose for services&lt;/li&gt;
&lt;li&gt;Keep DBs synchronized across environments&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Static Analysis
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use SonarQube or Code Climate&lt;/li&gt;
&lt;li&gt;Detect code smells and complexity&lt;/li&gt;
&lt;li&gt;Track code quality over time&lt;/li&gt;
&lt;li&gt;Integrate into CI pipeline&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  External Service Mocking
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Mock external HTTP services: nock or Mock-Server&lt;/li&gt;
&lt;li&gt;Simulate errors, delays, timeouts&lt;/li&gt;
&lt;li&gt;Test non-happy path flows&lt;/li&gt;
&lt;li&gt;Avoid hitting real external services in tests&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Middleware Testing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Test middlewares in isolation&lt;/li&gt;
&lt;li&gt;Stub {req, res, next} objects&lt;/li&gt;
&lt;li&gt;Verify middleware behavior independently&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Port Management
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Specify port in production&lt;/li&gt;
&lt;li&gt;Randomize port in testing (port 0)&lt;/li&gt;
&lt;li&gt;Prevent port collisions in parallel tests&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Test Five Outcomes
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Response validation&lt;/li&gt;
&lt;li&gt;State changes (DB, memory)&lt;/li&gt;
&lt;li&gt;Outgoing API calls&lt;/li&gt;
&lt;li&gt;Message queue events&lt;/li&gt;
&lt;li&gt;Observability (logs, metrics)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Production Best Practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Monitoring Strategy
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Monitor uptime, metrics, and user-facing symptoms&lt;/li&gt;
&lt;li&gt;Track Node.js-specific metrics (event loop lag)&lt;/li&gt;
&lt;li&gt;Use distributed tracing with Open Telemetry&lt;/li&gt;
&lt;li&gt;Implement comprehensive logging&lt;/li&gt;
&lt;li&gt;4 layers: uptime, metrics, distributed flows, logs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Smart Logging
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Plan logging platform from day 1&lt;/li&gt;
&lt;li&gt;Log to stdout, let environment handle routing&lt;/li&gt;
&lt;li&gt;Include transaction IDs (correlation IDs)&lt;/li&gt;
&lt;li&gt;Use AsyncLocalStorage for context propagation&lt;/li&gt;
&lt;li&gt;Enable log aggregation and analysis&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Reverse Proxy Delegation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Delegate CPU-intensive tasks (gzip, SSL)&lt;/li&gt;
&lt;li&gt;Use nginx, HAproxy, or cloud services&lt;/li&gt;
&lt;li&gt;Keep Node thread focused on application logic&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Dependency Management
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Lock dependencies with package-lock.json&lt;/li&gt;
&lt;li&gt;Commit lockfiles to version control&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;npm ci&lt;/code&gt; for consistent installs&lt;/li&gt;
&lt;li&gt;Ensure identical code across environments&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Process Management
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use platform-native solutions (Kubernetes, systemd)&lt;/li&gt;
&lt;li&gt;Avoid custom process managers in modern platforms&lt;/li&gt;
&lt;li&gt;Let infrastructure handle restarts and health checks&lt;/li&gt;
&lt;li&gt;Ensure process uptime with proper tools&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  CPU Utilization
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Replicate Node process for all CPU cores&lt;/li&gt;
&lt;li&gt;Use container orchestration for scaling&lt;/li&gt;
&lt;li&gt;Don't rely on Node cluster module alone&lt;/li&gt;
&lt;li&gt;Verify all cores are utilized&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Maintenance Endpoints
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Expose system information securely&lt;/li&gt;
&lt;li&gt;Provide memory usage, health checks&lt;/li&gt;
&lt;li&gt;Enable diagnostic operations&lt;/li&gt;
&lt;li&gt;Keep separate from public API&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  APM Integration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Add Application Performance Monitoring&lt;/li&gt;
&lt;li&gt;Auto-discover slow transactions&lt;/li&gt;
&lt;li&gt;Identify performance bottlenecks&lt;/li&gt;
&lt;li&gt;Provide developer context for errors&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Production-Ready Code
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Plan for production from day 1&lt;/li&gt;
&lt;li&gt;Consider maintainability early&lt;/li&gt;
&lt;li&gt;Design for operations and debugging&lt;/li&gt;
&lt;li&gt;Build with monitoring in mind&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Memory Management
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Watch Node process memory usage&lt;/li&gt;
&lt;li&gt;V8 has soft limits (1.4GB default)&lt;/li&gt;
&lt;li&gt;Monitor for memory leaks&lt;/li&gt;
&lt;li&gt;Alert on unusual memory growth&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Frontend Asset Management
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Serve frontend via nginx, S3, or CDN&lt;/li&gt;
&lt;li&gt;Don't serve static files through Node&lt;/li&gt;
&lt;li&gt;Exception: server-side rendering&lt;/li&gt;
&lt;li&gt;Keep Node focused on dynamic content&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Stateless Architecture
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Store data in external data stores&lt;/li&gt;
&lt;li&gt;Avoid in-process state (sessions, cache, files)&lt;/li&gt;
&lt;li&gt;Enable easy horizontal scaling&lt;/li&gt;
&lt;li&gt;Support instance reapp-ing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Vulnerability Detection
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use automated security scanning tools&lt;/li&gt;
&lt;li&gt;Monitor dependencies continuously&lt;/li&gt;
&lt;li&gt;Patch vulnerabilities immediately&lt;/li&gt;
&lt;li&gt;Scan locally and in CI/CD&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Transaction ID Logging
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Assign UUID to each request&lt;/li&gt;
&lt;li&gt;Use AsyncLocalStorage for context&lt;/li&gt;
&lt;li&gt;Include in all log statements&lt;/li&gt;
&lt;li&gt;Enable request flow tracing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Environment Configuration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Set NODE_ENV=production&lt;/li&gt;
&lt;li&gt;Enable production optimizations&lt;/li&gt;
&lt;li&gt;Libraries use environment for behavior&lt;/li&gt;
&lt;li&gt;Affects performance significantly&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Deployment Strategy
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Automate deployments completely&lt;/li&gt;
&lt;li&gt;Use Docker with CI/CD tools&lt;/li&gt;
&lt;li&gt;Implement zero-downtime deployments&lt;/li&gt;
&lt;li&gt;Make deployments atomic and reversible&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Node.js Version
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use LTS (Long Term Support) releases&lt;/li&gt;
&lt;li&gt;Receive critical bug fixes and security updates&lt;/li&gt;
&lt;li&gt;Ensure module compatibility&lt;/li&gt;
&lt;li&gt;Plan upgrade paths&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Log Routing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Log to stdout exclusively&lt;/li&gt;
&lt;li&gt;Let execution environment handle destinations&lt;/li&gt;
&lt;li&gt;Don't hard-code log destinations&lt;/li&gt;
&lt;li&gt;Support flexible log aggregation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Security Best Practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Linter Security Rules
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use eslint-plugin-security&lt;/li&gt;
&lt;li&gt;Catch vulnerabilities during development&lt;/li&gt;
&lt;li&gt;Prevent eval usage and code injection&lt;/li&gt;
&lt;li&gt;Detect insecure patterns early&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Rate Limiting
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Implement request limiting&lt;/li&gt;
&lt;li&gt;Prevent DOS attacks&lt;/li&gt;
&lt;li&gt;Use cloud load balancers, nginx, or rate-limiter-flexible&lt;/li&gt;
&lt;li&gt;Protect against abuse&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Secret Management
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Never store plain-text secrets in code&lt;/li&gt;
&lt;li&gt;Use Vault, Kubernetes Secrets, or environment variables&lt;/li&gt;
&lt;li&gt;Encrypt secrets in source control&lt;/li&gt;
&lt;li&gt;Implement pre-commit hooks&lt;/li&gt;
&lt;li&gt;Rotate keys regularly&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Query Injection Prevention
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use ORM/ODM libraries (Sequelize, Knex, Mongoose)&lt;/li&gt;
&lt;li&gt;Leverage parameterized queries&lt;/li&gt;
&lt;li&gt;Validate user input for expected types&lt;/li&gt;
&lt;li&gt;Never concatenate user input into queries&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security Checklist
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Enable HTTPS everywhere&lt;/li&gt;
&lt;li&gt;Use helmet.js for HTTP headers&lt;/li&gt;
&lt;li&gt;Implement CSRF protection&lt;/li&gt;
&lt;li&gt;Sanitize user input&lt;/li&gt;
&lt;li&gt;Use secure session cookies&lt;/li&gt;
&lt;li&gt;Implement proper authentication&lt;/li&gt;
&lt;li&gt;Apply principle of least privilege&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Dependency Security
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Scan for vulnerable dependencies&lt;/li&gt;
&lt;li&gt;Use npm audit or Snyk&lt;/li&gt;
&lt;li&gt;Update dependencies regularly&lt;/li&gt;
&lt;li&gt;Monitor security advisories&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Input Validation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Validate all user input&lt;/li&gt;
&lt;li&gt;Use validation libraries (joi, yup, zod)&lt;/li&gt;
&lt;li&gt;Implement allow-lists over deny-lists&lt;/li&gt;
&lt;li&gt;Validate data types and formats&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Authentication Best Practices
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use bcrypt or scrypt for passwords&lt;/li&gt;
&lt;li&gt;Implement 2FA where possible&lt;/li&gt;
&lt;li&gt;Use secure JWT practices&lt;/li&gt;
&lt;li&gt;Rotate secrets regularly&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Data Protection
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Escape HTML, JS, and CSS output&lt;/li&gt;
&lt;li&gt;Validate JSON schemas&lt;/li&gt;
&lt;li&gt;Implement proper access controls&lt;/li&gt;
&lt;li&gt;Encrypt sensitive data at rest&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Secure Headers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use helmet.js middleware&lt;/li&gt;
&lt;li&gt;Set Content-Security-Policy&lt;/li&gt;
&lt;li&gt;Enable HSTS&lt;/li&gt;
&lt;li&gt;Disable X-Powered-By&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Error Information Leakage
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Hide error details from clients&lt;/li&gt;
&lt;li&gt;Log detailed errors server-side&lt;/li&gt;
&lt;li&gt;Return generic error messages&lt;/li&gt;
&lt;li&gt;Don't expose stack traces in production&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Child Process Safety
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Avoid child_exec with user input&lt;/li&gt;
&lt;li&gt;Sanitize all arguments&lt;/li&gt;
&lt;li&gt;Use execFile over exec&lt;/li&gt;
&lt;li&gt;Implement timeouts&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  RegEx DOS Prevention
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Validate regex patterns&lt;/li&gt;
&lt;li&gt;Set timeouts for regex operations&lt;/li&gt;
&lt;li&gt;Test regex with long inputs&lt;/li&gt;
&lt;li&gt;Use safe-regex library&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Session Security
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use secure session configuration&lt;/li&gt;
&lt;li&gt;Set httpOnly and secure flags&lt;/li&gt;
&lt;li&gt;Implement session timeouts&lt;/li&gt;
&lt;li&gt;Rotate session IDs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  NPM Security
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Enable 2FA for npm account&lt;/li&gt;
&lt;li&gt;Audit packages before publishing&lt;/li&gt;
&lt;li&gt;Use .npmignore to prevent secret leaks&lt;/li&gt;
&lt;li&gt;Review dependencies regularly&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Module Loading Security
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Avoid dynamic requires with user input&lt;/li&gt;
&lt;li&gt;Use static imports when possible&lt;/li&gt;
&lt;li&gt;Validate module paths&lt;/li&gt;
&lt;li&gt;Implement sandbox for untrusted code&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Redirect Safety
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Validate redirect URLs&lt;/li&gt;
&lt;li&gt;Use allow-list for redirects&lt;/li&gt;
&lt;li&gt;Prevent open redirect vulnerabilities&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Built-in Module Usage
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Import built-in modules with 'node:' protocol&lt;/li&gt;
&lt;li&gt;Example: &lt;code&gt;import fs from 'node:fs'&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Makes built-in modules explicit&lt;/li&gt;
&lt;li&gt;Prevents shadowing attacks&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Docker Best Practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Multi-Stage Builds
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use multi-stage builds for smaller images&lt;/li&gt;
&lt;li&gt;Separate build and runtime dependencies&lt;/li&gt;
&lt;li&gt;Reduce attack surface&lt;/li&gt;
&lt;li&gt;Improve security and performance&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Process Bootstrap
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;node&lt;/code&gt; command directly, avoid &lt;code&gt;npm start&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Faster startup, proper signal handling&lt;/li&gt;
&lt;li&gt;No unnecessary npm process overhead&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Container Runtime
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Let orchestrator handle replication&lt;/li&gt;
&lt;li&gt;Use Kubernetes/Docker Swarm for uptime&lt;/li&gt;
&lt;li&gt;Don't run process manager inside container&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Secret Protection
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use .dockerignore effectively&lt;/li&gt;
&lt;li&gt;Never commit secrets to images&lt;/li&gt;
&lt;li&gt;Use Docker secrets or environment variables&lt;/li&gt;
&lt;li&gt;Clean secrets after build&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Dependency Cleanup
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;npm ci --production&lt;/code&gt; in final stage&lt;/li&gt;
&lt;li&gt;Remove devDependencies&lt;/li&gt;
&lt;li&gt;Clean npm cache&lt;/li&gt;
&lt;li&gt;Minimize image size&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Graceful Shutdown
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Handle SIGTERM properly&lt;/li&gt;
&lt;li&gt;Implement health checks&lt;/li&gt;
&lt;li&gt;Clean up connections on shutdown&lt;/li&gt;
&lt;li&gt;Drain requests before exit&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Memory Limits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Set Docker memory limits&lt;/li&gt;
&lt;li&gt;Configure V8 max-old-space-size&lt;/li&gt;
&lt;li&gt;Prevent OOM kills&lt;/li&gt;
&lt;li&gt;Match container and V8 limits&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Image Caching
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Order Dockerfile for optimal caching&lt;/li&gt;
&lt;li&gt;Copy package.json before source code&lt;/li&gt;
&lt;li&gt;Leverage layer caching&lt;/li&gt;
&lt;li&gt;Minimize cache invalidation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Image Tagging
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use explicit image references&lt;/li&gt;
&lt;li&gt;Avoid 'latest' tag in production&lt;/li&gt;
&lt;li&gt;Pin dependencies to versions&lt;/li&gt;
&lt;li&gt;Ensure reproducible builds&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Base Image Selection
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Prefer Alpine or slim variants&lt;/li&gt;
&lt;li&gt;Minimize base image size&lt;/li&gt;
&lt;li&gt;Reduce vulnerabilities&lt;/li&gt;
&lt;li&gt;Use official Node.js images&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Build Secrets
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use BuildKit secret mounts&lt;/li&gt;
&lt;li&gt;Never use ARG for secrets&lt;/li&gt;
&lt;li&gt;Secrets don't persist in layers&lt;/li&gt;
&lt;li&gt;Clean build-time secrets&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Image Scanning
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Scan for vulnerabilities (Snyk, Trivy)&lt;/li&gt;
&lt;li&gt;Check multiple layers&lt;/li&gt;
&lt;li&gt;Integrate into CI/CD&lt;/li&gt;
&lt;li&gt;Fix critical vulnerabilities&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cache Management
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Clean node_modules cache&lt;/li&gt;
&lt;li&gt;Remove unnecessary files&lt;/li&gt;
&lt;li&gt;Use .dockerignore&lt;/li&gt;
&lt;li&gt;Minimize layer size&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Dockerfile Linting
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use hadolint for linting&lt;/li&gt;
&lt;li&gt;Follow best practices&lt;/li&gt;
&lt;li&gt;Catch common mistakes&lt;/li&gt;
&lt;li&gt;Integrate into CI&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Code Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Proper Error Handling
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Do: Use AppError extending Error&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppError&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Error&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="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;httpCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isOperational&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&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;httpCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;httpCode&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;isOperational&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isOperational&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;captureStackTrace&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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Usage&lt;/span&gt;
&lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AppError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ValidationError&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Async-Await Pattern
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Do: Use async-await&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;userRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findById&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Failed to get user&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="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AppError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UserNotFound&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User not found&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;404&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="c1"&gt;// Avoid: Callbacks&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getUser&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="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;userRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&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;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configuration Management
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Do: Use convict or similar&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;convict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;convict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;convict&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;development&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;development&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;NODE_ENV&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;port&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PORT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;localhost&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DB_HOST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;allowed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;strict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Logging with Context
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Do: Use AsyncLocalStorage for transaction ID&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AsyncLocalStorage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;async_hooks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;asyncLocalStorage&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;AsyncLocalStorage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;logWithContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;asyncLocalStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getStore&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&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="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="na"&gt;transactionId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;transactionId&lt;/span&gt; 
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Middleware to set context&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transactionId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;v4&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;asyncLocalStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;transactionId&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;next&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;
  
  
  Input Validation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Do: Use validation library&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Joi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;joi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Joi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Joi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Joi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Joi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;validateUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;userSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AppError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ValidationError&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;400&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;value&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;
  
  
  Security Headers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Do: Use helmet&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;helmet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;helmet&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;helmet&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;helmet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contentSecurityPolicy&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;directives&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;defaultSrc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;'self'&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;styleSrc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;'self'&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;'unsafe-inline'&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;scriptSrc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;'self'&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;imgSrc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;'self'&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Summary Checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Structure by business components&lt;/li&gt;
&lt;li&gt;[ ] Use 3-tier layering (entry-points, domain, data-access)&lt;/li&gt;
&lt;li&gt;[ ] Implement centralized error handling&lt;/li&gt;
&lt;li&gt;[ ] Use async-await exclusively&lt;/li&gt;
&lt;li&gt;[ ] Configure ESLint with security plugins&lt;/li&gt;
&lt;li&gt;[ ] Write API tests minimum&lt;/li&gt;
&lt;li&gt;[ ] Use mature logger (Pino/Winston)&lt;/li&gt;
&lt;li&gt;[ ] Implement rate limiting&lt;/li&gt;
&lt;li&gt;[ ] Validate all user input&lt;/li&gt;
&lt;li&gt;[ ] Lock dependencies&lt;/li&gt;
&lt;li&gt;[ ] Use environment variables for config&lt;/li&gt;
&lt;li&gt;[ ] Monitor with APM tools&lt;/li&gt;
&lt;li&gt;[ ] Set NODE_ENV=production&lt;/li&gt;
&lt;li&gt;[ ] Log to stdout only&lt;/li&gt;
&lt;li&gt;[ ] Use Docker multi-stage builds&lt;/li&gt;
&lt;li&gt;[ ] Implement graceful shutdown&lt;/li&gt;
&lt;li&gt;[ ] Scan for vulnerabilities&lt;/li&gt;
&lt;li&gt;[ ] Use LTS Node.js version&lt;/li&gt;
&lt;li&gt;[ ] Enable TypeScript thoughtfully&lt;/li&gt;
&lt;li&gt;[ ] Test error flows&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Main Repository: &lt;a href="https://github.com/goldbergyoni/nodebestpractices" rel="noopener noreferrer"&gt;https://github.com/goldbergyoni/nodebestpractices&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;JavaScript Testing: &lt;a href="https://github.com/goldbergyoni/javascript-testing-best-practices" rel="noopener noreferrer"&gt;https://github.com/goldbergyoni/javascript-testing-best-practices&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Node.js Integration Tests: &lt;a href="https://github.com/testjavascript/nodejs-integration-tests-best-practices" rel="noopener noreferrer"&gt;https://github.com/testjavascript/nodejs-integration-tests-best-practices&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>javascript</category>
      <category>node</category>
      <category>architecture</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Dapper no .NET: simplicidade e performance no acesso a dados</title>
      <dc:creator>Danilo Itagyba</dc:creator>
      <pubDate>Wed, 03 Sep 2025 13:03:46 +0000</pubDate>
      <link>https://forem.com/itagyba/dapper-no-net-simplicidade-e-performance-no-acesso-a-dados-3c1</link>
      <guid>https://forem.com/itagyba/dapper-no-net-simplicidade-e-performance-no-acesso-a-dados-3c1</guid>
      <description>&lt;p&gt;Quando pensamos em acesso a banco de dados no .NET, o &lt;strong&gt;Entity Framework&lt;/strong&gt; costuma ser a escolha padrão. Ele oferece recursos avançados de ORM, mas nem sempre precisamos de toda essa complexidade. Em cenários onde &lt;strong&gt;performance e simplicidade&lt;/strong&gt; são prioridade, o &lt;strong&gt;Dapper&lt;/strong&gt; se destaca como alternativa leve e eficiente.  &lt;/p&gt;




&lt;h2&gt;
  
  
  O que é o Dapper?
&lt;/h2&gt;

&lt;p&gt;O &lt;strong&gt;Dapper&lt;/strong&gt; é uma biblioteca open source criada pela equipe do Stack Overflow. Ele é conhecido como um &lt;strong&gt;micro-ORM&lt;/strong&gt;, pois não tenta abstrair completamente o banco de dados. Em vez disso, fornece um jeito simples e rápido de mapear resultados de queries SQL para objetos C#.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📦 Pacote: &lt;code&gt;Dapper&lt;/code&gt; (disponível no NuGet)
&lt;/li&gt;
&lt;li&gt;⚡ Performance: próximo do ADO.NET puro, mas com muito menos código
&lt;/li&gt;
&lt;li&gt;🎯 Ideal quando você já tem queries SQL prontas e quer apenas mapear resultados para objetos
&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;No seu projeto .NET, basta rodar:  &lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet add package Dapper&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Primeiro Exemplo com Dapper
&lt;/h2&gt;

&lt;p&gt;Suponha que temos uma tabela &lt;strong&gt;Products&lt;/strong&gt; no banco:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;CREATE TABLE Products (&lt;br&gt;
    Id INT PRIMARY KEY,&lt;br&gt;
    Name NVARCHAR(100),&lt;br&gt;
    Price DECIMAL(10,2)&lt;br&gt;
)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;E uma classe em C#:&lt;br&gt;
&lt;code&gt;public class Product &lt;br&gt;
{&lt;br&gt;
    public int Id { get; set; }&lt;br&gt;
    public string Name { get; set; }&lt;br&gt;
    public decimal Price { get; set; }&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Com Dapper, podemos buscar todos os produtos assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System.Data.SqlClient;
using Dapper;

string connectionString = "Server=.;Database=MyDb;Trusted_Connection=True;";

using (var connection = new SqlConnection(connectionString))
{
    var products = connection.Query&amp;lt;Product&amp;gt;("SELECT * FROM Products").ToList();

    foreach (var p in products)
    {
        Console.WriteLine($"{p.Id} - {p.Name} - {p.Price:C}");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Em apenas duas linhas de código (Query + ToList()), já temos os dados do banco mapeados para objetos.&lt;/p&gt;

&lt;p&gt;Inserindo Dados com Dapper:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var sql = "INSERT INTO Products (Name, Price) VALUES (@Name, @Price)";

var newProduct = new Product { Name = "Notebook", Price = 3500.00m };

using (var connection = new SqlConnection(connectionString))
{
    connection.Execute(sql, newProduct);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui o Dapper faz o binding automático das propriedades Name e Price do objeto para os parâmetros &lt;a class="mentioned-user" href="https://dev.to/name"&gt;@name&lt;/a&gt; e &lt;a class="mentioned-user" href="https://dev.to/price"&gt;@price&lt;/a&gt; da query.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vantagens do Dapper&lt;/strong&gt;&lt;br&gt;
✔️ Simplicidade – menos código para mapear dados&lt;br&gt;
✔️ Performance – quase tão rápido quanto ADO.NET puro&lt;br&gt;
✔️ Flexibilidade – você escreve o SQL, o Dapper só faz o mapeamento&lt;br&gt;
✔️ Integração fácil – funciona bem junto com Entity Framework, se quiser misturar&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quando usar o Dapper?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Projetos que exigem alta performance.&lt;/p&gt;

&lt;p&gt;Sistemas que já usam queries SQL prontas.&lt;/p&gt;

&lt;p&gt;Aplicações pequenas ou médias onde um ORM completo seria “overkill”.&lt;/p&gt;

&lt;p&gt;Microserviços, APIs e jobs que só precisam de consultas rápidas.&lt;/p&gt;

&lt;p&gt;Se você precisa de lazy loading, migrations ou LINQ avançado, provavelmente o Entity Framework continua sendo a melhor opção.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusão&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O Dapper é a escolha perfeita quando você quer controle total sobre suas queries SQL, mas não quer lidar com toda a verbosidade do ADO.NET. Ele equilibra performance, simplicidade e produtividade de uma forma difícil de ignorar.&lt;/p&gt;

&lt;p&gt;Se o seu projeto .NET precisa de acesso a dados rápido e direto ao ponto, vale a pena experimentar o Dapper.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
