<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Antoniel Magalhães</title>
    <description>The latest articles on DEV Community by Antoniel Magalhães (@antoniel).</description>
    <link>https://dev.to/antoniel</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%2F438425%2F97cc4cd8-6fac-4353-9aaf-06d89d32b07a.jpeg</url>
      <title>DEV Community: Antoniel Magalhães</title>
      <link>https://dev.to/antoniel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/antoniel"/>
    <language>en</language>
    <item>
      <title>Seu time não merece revisar seu PR</title>
      <dc:creator>Antoniel Magalhães</dc:creator>
      <pubDate>Sat, 07 Mar 2026 02:34:58 +0000</pubDate>
      <link>https://dev.to/antoniel/seu-time-nao-merece-revisar-seu-pr-2io7</link>
      <guid>https://dev.to/antoniel/seu-time-nao-merece-revisar-seu-pr-2io7</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; Como usar IA e stacked PRs para facilitar a vida do seu time na revisão de um PR grande.&lt;/p&gt;

&lt;p&gt;Publicado originalmente em &lt;a href="https://antoniel.sh/blog/stop-dumping-10k-line-prs" rel="noopener noreferrer"&gt;antoniel.sh&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  O problema
&lt;/h2&gt;

&lt;p&gt;Você abre um PR e percebe que ele tem algo em torno de 10 mil linhas de mudança. Nesse ponto, o problema não é só o tamanho do código. É a experiência de review. Um PR desse tamanho é difícil de entender, fácil de adiar e fácil de revisar mal.&lt;/p&gt;

&lt;p&gt;Em retrospecto, isso deveria ter sido uma stack desde o começo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stacked PRs
&lt;/h2&gt;

&lt;p&gt;A primeira explicação clara de stacked PRs que vi foi na talk do Tomas Reimers na GitKon 2022 sobre o tema: &lt;a href="https://www.youtube.com/watch?v=U8wJoxxmskM&amp;amp;t=1s" rel="noopener noreferrer"&gt;Stacked Pull Requests | GitKon 2022 | Tomas Reimers, Graphite&lt;/a&gt;. A ideia é simples: em vez de um PR gigante, você cria uma sequência de PRs menores, em que cada um se apoia no anterior.&lt;/p&gt;

&lt;p&gt;Graphite é uma das ferramentas associadas a esse workflow, mas a ideia principal independe da ferramenta. Uma stack é mais fácil de revisar porque cada PR carrega uma parte da história.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Um PR gigante&lt;/th&gt;
&lt;th&gt;Stacked PRs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Um review com contexto demais&lt;/td&gt;
&lt;td&gt;Vários reviews com limites claros&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Refactors e feature work misturados&lt;/td&gt;
&lt;td&gt;Cada PR carrega uma parte da mudança&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fácil de adiar ou revisar por cima&lt;/td&gt;
&lt;td&gt;Mais fácil de revisar em ordem&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Um guia prático
&lt;/h2&gt;

&lt;p&gt;Idealmente, você planeja a stack desde o começo e agrupa as mudanças por entrega. Mas às vezes você só percebe o problema quando o PR já está grande demais. Nesse caso, a IA pode ajudar a quebrar a branch em uma stack revisável com muito menos trabalho manual.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Peça para a IA dividir a branch em stacked PRs.&lt;/li&gt;
&lt;li&gt;Valide que a branch final da stack preserva a mudança original.&lt;/li&gt;
&lt;li&gt;Peça para a IA gerar o fluxo de &lt;code&gt;gh&lt;/code&gt; para abrir os PRs em ordem.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Usando IA para criar a stack
&lt;/h3&gt;

&lt;p&gt;Esse é um daqueles casos em que o prompt pode continuar simples.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;My branch against &lt;code&gt;main&lt;/code&gt; has a huge diff. Split it into stacked PRs. Create the branches locally and I will push them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O resultado pode voltar em um formato como este:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I split the branch into 5 stacked PRs.

Merge order:
1. stacked (foundation)
2. 02-api-cleanup (base: stacked)
3. 03-shared-types (base: 02-api-cleanup)
4. 04-backend-flow (base: 03-shared-types)
5. 05-frontend-flow (base: 04-backend-flow)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Como validar que nada se perdeu
&lt;/h2&gt;

&lt;h3&gt;
  
  
  A verificação que importa
&lt;/h3&gt;

&lt;p&gt;Quando a IA propõe a stack, o próximo passo é validar.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I need a quick way to compare the original branch with the final stacked branch and verify that nothing important was lost.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Isso te dá um comando como este:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git &lt;span class="nt"&gt;--no-pager&lt;/span&gt; diff main &amp;lt;original-branch&amp;gt; &lt;span class="nt"&gt;--shortstat&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git &lt;span class="nt"&gt;--no-pager&lt;/span&gt; diff main &amp;lt;last-stacked-branch&amp;gt; &lt;span class="nt"&gt;--shortstat&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se os dois resumos forem efetivamente iguais, a branch final da stack preserva a mudança original. Pequenas diferenças de formatação são aceitáveis; o formato geral do diff deve continuar o mesmo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;61 files changed, 10234 insertions(+), 487 deletions(-)
61 files changed, 10240 insertions(+), 492 deletions(-)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Automatizando a abertura dos PRs com gh CLI
&lt;/h2&gt;

&lt;p&gt;Depois que o diff confere, o problema restante é operacional: abrir cada PR e configurar a base correta.&lt;/p&gt;

&lt;h3&gt;
  
  
  O fluxo com &lt;code&gt;gh&lt;/code&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;I already have the stacked branches. Give me a &lt;code&gt;gh&lt;/code&gt; CLI flow to open the PRs in order and set each base branch correctly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Faça push de todas as branches primeiro e depois use o fluxo gerado com &lt;code&gt;gh&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;PR1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;create &lt;span class="nt"&gt;--base&lt;/span&gt; main &lt;span class="nt"&gt;--head&lt;/span&gt; &amp;lt;stacked-1&amp;gt; &lt;span class="nt"&gt;--title&lt;/span&gt; &lt;span class="s2"&gt;"[1/5] Foundation changes"&lt;/span&gt; &lt;span class="nt"&gt;--body&lt;/span&gt; &lt;span class="s2"&gt;"Stack 1 of PROJECT-123"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oE&lt;/span&gt; &lt;span class="s1"&gt;'[0-9]+$'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;PR2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;create &lt;span class="nt"&gt;--base&lt;/span&gt; &amp;lt;stacked-1&amp;gt; &lt;span class="nt"&gt;--head&lt;/span&gt; &amp;lt;stacked-2&amp;gt; &lt;span class="nt"&gt;--title&lt;/span&gt; &lt;span class="s2"&gt;"[2/5] API cleanup"&lt;/span&gt; &lt;span class="nt"&gt;--body&lt;/span&gt; &lt;span class="s2"&gt;"Depends on #&lt;/span&gt;&lt;span class="nv"&gt;$PR1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oE&lt;/span&gt; &lt;span class="s1"&gt;'[0-9]+$'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;PR3&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;create &lt;span class="nt"&gt;--base&lt;/span&gt; &amp;lt;stacked-2&amp;gt; &lt;span class="nt"&gt;--head&lt;/span&gt; &amp;lt;stacked-3&amp;gt; &lt;span class="nt"&gt;--title&lt;/span&gt; &lt;span class="s2"&gt;"[3/5] Shared types"&lt;/span&gt; &lt;span class="nt"&gt;--body&lt;/span&gt; &lt;span class="s2"&gt;"Depends on #&lt;/span&gt;&lt;span class="nv"&gt;$PR2&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oE&lt;/span&gt; &lt;span class="s1"&gt;'[0-9]+$'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;PR4&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;create &lt;span class="nt"&gt;--base&lt;/span&gt; &amp;lt;stacked-3&amp;gt; &lt;span class="nt"&gt;--head&lt;/span&gt; &amp;lt;stacked-4&amp;gt; &lt;span class="nt"&gt;--title&lt;/span&gt; &lt;span class="s2"&gt;"[4/5] Backend flow"&lt;/span&gt; &lt;span class="nt"&gt;--body&lt;/span&gt; &lt;span class="s2"&gt;"Depends on #&lt;/span&gt;&lt;span class="nv"&gt;$PR3&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oE&lt;/span&gt; &lt;span class="s1"&gt;'[0-9]+$'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
gh &lt;span class="nb"&gt;pr &lt;/span&gt;create &lt;span class="nt"&gt;--base&lt;/span&gt; &amp;lt;stacked-4&amp;gt; &lt;span class="nt"&gt;--head&lt;/span&gt; &amp;lt;stacked-5&amp;gt; &lt;span class="nt"&gt;--title&lt;/span&gt; &lt;span class="s2"&gt;"[5/5] Frontend flow"&lt;/span&gt; &lt;span class="nt"&gt;--body&lt;/span&gt; &lt;span class="s2"&gt;"Depends on #&lt;/span&gt;&lt;span class="nv"&gt;$PR4&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cada &lt;code&gt;gh pr create&lt;/code&gt; retorna a URL do PR; &lt;code&gt;grep -oE '[0-9]+$'&lt;/code&gt; extrai o número para o próximo &lt;code&gt;Depends on #N&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A lição
&lt;/h2&gt;

&lt;p&gt;Se o trabalho pertence a uma stack, faça uma stack. Idealmente, desde o começo. Se você percebeu tarde demais, peça ajuda para a IA dividir, validar e abrir os PRs.&lt;/p&gt;

</description>
      <category>github</category>
      <category>ai</category>
      <category>codereview</category>
      <category>programming</category>
    </item>
    <item>
      <title>Stop F*cking Your Team With Giant PRs</title>
      <dc:creator>Antoniel Magalhães</dc:creator>
      <pubDate>Sat, 07 Mar 2026 02:33:18 +0000</pubDate>
      <link>https://dev.to/antoniel/stop-fcking-your-team-with-giant-prs-4nff</link>
      <guid>https://dev.to/antoniel/stop-fcking-your-team-with-giant-prs-4nff</guid>
      <description>&lt;p&gt;Originally published on &lt;a href="https://antoniel.sh/blog/stop-dumping-10k-line-prs" rel="noopener noreferrer"&gt;antoniel.sh&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; How to use AI and stacked PRs to make life easier for your team when reviewing a large PR.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;You open a PR and realize it has around 10k lines of changes. At that point, the problem is not only the code size. It is the review experience. A PR that large is hard to reason about, easy to postpone, and easy to review poorly.&lt;/p&gt;

&lt;p&gt;In retrospect, it should have been a stack from the start.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stacked PRs
&lt;/h2&gt;

&lt;p&gt;The first clear explanation of stacked PRs I saw was in Tomas Reimers's GitKon 2022 talk on the topic: &lt;a href="https://www.youtube.com/watch?v=U8wJoxxmskM&amp;amp;t=1s" rel="noopener noreferrer"&gt;Stacked Pull Requests | GitKon 2022 | Tomas Reimers, Graphite&lt;/a&gt;. The idea is simple: instead of one giant PR, you create a sequence of smaller PRs where each one builds on the previous one.&lt;/p&gt;

&lt;p&gt;Graphite is one of the tools associated with that workflow, but the key idea is independent of any tool. A stack is easier to review because each PR carries one part of the story.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;One huge PR&lt;/th&gt;
&lt;th&gt;Stacked PRs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;One review with too much context&lt;/td&gt;
&lt;td&gt;Multiple reviews with clear boundaries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Refactors and feature work mixed together&lt;/td&gt;
&lt;td&gt;Each PR carries one part of the change&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Easy to postpone or skim&lt;/td&gt;
&lt;td&gt;Easier to review in order&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  A practical guide
&lt;/h2&gt;

&lt;p&gt;Ideally, you plan the stack from the beginning and group changes by delivery. But sometimes you only notice the problem when the PR is already too large. In that case, AI can help you break the branch into a reviewable stack with much less manual work.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ask AI to split the branch into stacked PRs.&lt;/li&gt;
&lt;li&gt;Validate that the final stacked branch preserves the original change.&lt;/li&gt;
&lt;li&gt;Ask AI to generate the &lt;code&gt;gh&lt;/code&gt; flow to open the PRs in order.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Using AI to stack PRs
&lt;/h3&gt;

&lt;p&gt;This is one of those cases where the prompt can stay simple.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;My branch against &lt;code&gt;main&lt;/code&gt; has a huge diff. Split it into stacked PRs. Create the branches locally and I will push them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The result can come back in a format like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I split the branch into 5 stacked PRs.

Merge order:
1. stacked (foundation)
2. 02-api-cleanup (base: stacked)
3. 03-shared-types (base: 02-api-cleanup)
4. 04-backend-flow (base: 03-shared-types)
5. 05-frontend-flow (base: 04-backend-flow)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to validate nothing was lost
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The check that matters
&lt;/h3&gt;

&lt;p&gt;Once the AI gives you a proposed stack, the next step is validation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I need a quick way to compare the original branch with the final stacked branch and verify that nothing important was lost.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That gives you a command like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git &lt;span class="nt"&gt;--no-pager&lt;/span&gt; diff main &amp;lt;original-branch&amp;gt; &lt;span class="nt"&gt;--shortstat&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git &lt;span class="nt"&gt;--no-pager&lt;/span&gt; diff main &amp;lt;last-stacked-branch&amp;gt; &lt;span class="nt"&gt;--shortstat&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If both summaries are effectively the same, the stacked branch preserves the original change. Small formatting differences are fine; the overall shape of the diff should remain the same.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;61 files changed, 10234 insertions(+), 487 deletions(-)
61 files changed, 10240 insertions(+), 492 deletions(-)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Automating PR creation with gh CLI
&lt;/h2&gt;

&lt;p&gt;Once the diff checks out, the remaining problem is operational: opening each PR and setting the right base branch.&lt;/p&gt;

&lt;h3&gt;
  
  
  The &lt;code&gt;gh&lt;/code&gt; flow
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;I already have the stacked branches. Give me a &lt;code&gt;gh&lt;/code&gt; CLI flow to open the PRs in order and set each base branch correctly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Push all branches first, then use the generated &lt;code&gt;gh&lt;/code&gt; flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;PR1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;create &lt;span class="nt"&gt;--base&lt;/span&gt; main &lt;span class="nt"&gt;--head&lt;/span&gt; &amp;lt;stacked-1&amp;gt; &lt;span class="nt"&gt;--title&lt;/span&gt; &lt;span class="s2"&gt;"[1/5] Foundation changes"&lt;/span&gt; &lt;span class="nt"&gt;--body&lt;/span&gt; &lt;span class="s2"&gt;"Stack 1 of PROJECT-123"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oE&lt;/span&gt; &lt;span class="s1"&gt;'[0-9]+$'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;PR2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;create &lt;span class="nt"&gt;--base&lt;/span&gt; &amp;lt;stacked-1&amp;gt; &lt;span class="nt"&gt;--head&lt;/span&gt; &amp;lt;stacked-2&amp;gt; &lt;span class="nt"&gt;--title&lt;/span&gt; &lt;span class="s2"&gt;"[2/5] API cleanup"&lt;/span&gt; &lt;span class="nt"&gt;--body&lt;/span&gt; &lt;span class="s2"&gt;"Depends on #&lt;/span&gt;&lt;span class="nv"&gt;$PR1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oE&lt;/span&gt; &lt;span class="s1"&gt;'[0-9]+$'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;PR3&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;create &lt;span class="nt"&gt;--base&lt;/span&gt; &amp;lt;stacked-2&amp;gt; &lt;span class="nt"&gt;--head&lt;/span&gt; &amp;lt;stacked-3&amp;gt; &lt;span class="nt"&gt;--title&lt;/span&gt; &lt;span class="s2"&gt;"[3/5] Shared types"&lt;/span&gt; &lt;span class="nt"&gt;--body&lt;/span&gt; &lt;span class="s2"&gt;"Depends on #&lt;/span&gt;&lt;span class="nv"&gt;$PR2&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oE&lt;/span&gt; &lt;span class="s1"&gt;'[0-9]+$'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;PR4&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;create &lt;span class="nt"&gt;--base&lt;/span&gt; &amp;lt;stacked-3&amp;gt; &lt;span class="nt"&gt;--head&lt;/span&gt; &amp;lt;stacked-4&amp;gt; &lt;span class="nt"&gt;--title&lt;/span&gt; &lt;span class="s2"&gt;"[4/5] Backend flow"&lt;/span&gt; &lt;span class="nt"&gt;--body&lt;/span&gt; &lt;span class="s2"&gt;"Depends on #&lt;/span&gt;&lt;span class="nv"&gt;$PR3&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oE&lt;/span&gt; &lt;span class="s1"&gt;'[0-9]+$'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
gh &lt;span class="nb"&gt;pr &lt;/span&gt;create &lt;span class="nt"&gt;--base&lt;/span&gt; &amp;lt;stacked-4&amp;gt; &lt;span class="nt"&gt;--head&lt;/span&gt; &amp;lt;stacked-5&amp;gt; &lt;span class="nt"&gt;--title&lt;/span&gt; &lt;span class="s2"&gt;"[5/5] Frontend flow"&lt;/span&gt; &lt;span class="nt"&gt;--body&lt;/span&gt; &lt;span class="s2"&gt;"Depends on #&lt;/span&gt;&lt;span class="nv"&gt;$PR4&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each &lt;code&gt;gh pr create&lt;/code&gt; returns the PR URL; &lt;code&gt;grep -oE '[0-9]+$'&lt;/code&gt; extracts the number for the next &lt;code&gt;Depends on #N&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The lesson
&lt;/h2&gt;

&lt;p&gt;If the work belongs in a stack, make it a stack. Ideally, do it from the beginning. If you notice too late, ask AI to help you split, validate, and open the PRs.&lt;/p&gt;

</description>
      <category>codereview</category>
      <category>ai</category>
      <category>github</category>
    </item>
    <item>
      <title>Meu Processo de Agentic Engineering: Do Vibe Code ao BDD</title>
      <dc:creator>Antoniel Magalhães</dc:creator>
      <pubDate>Thu, 05 Mar 2026 15:44:00 +0000</pubDate>
      <link>https://dev.to/antoniel/meu-processo-de-agentic-engineering-do-vibe-code-ao-bd-5418</link>
      <guid>https://dev.to/antoniel/meu-processo-de-agentic-engineering-do-vibe-code-ao-bd-5418</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; Uso BDD para transformar especificação em código validado. Os cenários definem o comportamento; os testes cobrem; a mutação confere se os testes são de fato úteis. Depois de validado, consigo refatorar a implementação sem medo de regressão.&lt;/p&gt;

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

&lt;p&gt;Este post trata de como eu atualmente lido com agentic engineering e de como tento criar features usando agentes de IA (Cursor, Claude Code, ou qualquer outro) por meio de uma metodologia definida, especificamente BDD (Behavior Driven Design) para guiar a produção de código e garantir a corretude.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vibe Code vs Agent Engineering
&lt;/h2&gt;

&lt;p&gt;A primeira vez que vi o termo agentic engineering aparecer foi no &lt;a href="https://simonwillison.net/2026/Feb/23/agentic-engineering-patterns/" rel="noopener noreferrer"&gt;artigo do Simon Willison sobre padrões de agentic engineering&lt;/a&gt;. Eu já praticava isso, mas continuava chamando de vibe coding e eu gostei da nomenclatura, parece algo mais sério e bem definido.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vibe coding
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Quando você não presta atenção no código de forma geral&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Não presta atenção em como as coisas estão sendo feitas. O foco está em entregar, não em estabelecer padrões ou validar a qualidade do que o agente produz.&lt;/p&gt;

&lt;h3&gt;
  
  
  Agentic engineering
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Quando você cria e estabelece normas&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Cria normas, guidelines e define as formas como quer que o código seja escrito pela IA. Você ainda não digita; mas influencia ativamente como o código é produzido.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explorando novos padrões de agentic engineering
&lt;/h2&gt;

&lt;p&gt;No dia a dia, é difícil abrir mão de produtividade ou qualidade em relação à baseline só para experimentar padrões de agentic engineering. Então o que faço normalmente é criar pequenos side projects que quero fazer e usá-los para explorar essas capacidades com o agente.&lt;/p&gt;

&lt;p&gt;Comecei o projeto com meu workflow já estabelecido de agentic engineering que é: eu tenho uma intenção, crio uma especificação usando SpecKit ou OpenSpec, a partir da especificação eu crio um plano, e desse plano eu crio a implementação.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Intenção → Especificação → Plano → Implementação
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Um pipeline simples, mas que funciona bem para mim. O "problema" é que preciso estar atento em todas as etapas: a intenção está na minha mente; tenho que confirmar que a especificação reflete o que imaginei; verificar se o plano de implementação segue como eu imaginei; e no final fazer code review da implementação. Esse é um processo que exige bastante da minha atenção e minha vontade era explorar diferentes padrões que pudessem reduzir o meu tempo de atenção por tarefa mas mantendo a mesma qualidade.&lt;/p&gt;

&lt;h2&gt;
  
  
  TDD
&lt;/h2&gt;

&lt;p&gt;Já tinha visto o padrão de usar testes automatizados para validar a implementação e criar essa contrapressão no agente para que ele valide o próprio trabalho. Acho válido. O problema, na minha experiência, é que quando deixo o agente criar os testes sozinho, sem supervisão adequada, ele acaba pegando atalhos: testes que cobrem coisas triviais e detalhes de implementação. Coisas como &lt;code&gt;expect(1).toBe(1)&lt;/code&gt; e afins.&lt;/p&gt;

&lt;p&gt;O Simon documenta o &lt;a href="https://simonwillison.net/guides/agentic-engineering-patterns/red-green-tdd/" rel="noopener noreferrer"&gt;padrão de TDD com red/green em seu guia&lt;/a&gt;: fazer o teste falhar e depois fazê-lo passar, garantindo que o teste é realmente útil. Dada a minha experiência, ainda não me sentia à vontade confiando na boa vontade do agente de não editar o teste só para fazê-lo passar (&lt;a href="https://x.com/effectfully/status/2029364333919060123" rel="noopener noreferrer"&gt;@effectfully&lt;/a&gt;). Meu pior cenário: implemento TDD, levo &lt;code&gt;n&lt;/code&gt; minutos, vou revisar o código, especificamente os testes e os testes não fazem sentido ou faço um teste manual e descubro que a feature não funciona, e os testes passam.&lt;/p&gt;

&lt;h3&gt;
  
  
  Antes: Just Go
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Fluxo anterior sem especificação formal&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Abrir o agente, explicar a tarefa, refinar ao longo das iterações. Sem spec, sem validação formal. O risco: testes triviais, implementação que passa mas não entrega o esperado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Explicar tarefa → Agente implementa → Revisar → OK? → (Não → Agente implementa) | (Sim → Pronto)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Depois: BDD
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Especificação para ação&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Spec → .feature → tony-bdd-test → mutação. Cenários aprovados viram fonte de verdade; testes validam comportamento; mutação garante que os testes não passam por acaso.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Spec → .feature → tony-bdd-test → Mutação
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  BDD
&lt;/h2&gt;

&lt;p&gt;Há um tempo atrás, em tempos pré-llms, me deparei com um requisito: como garantir a qualidade do código através de testes que conversam com o produto? Havia um descompasso entre o que era pedido no ticket e o que o time entregava. A solução: BDD (Behavior Driven Design), &lt;a href="https://cucumber.io/docs/bdd/" rel="noopener noreferrer"&gt;documentado pela Cucumber&lt;/a&gt;. Uma vez aprovados os arquivos &lt;code&gt;.feature&lt;/code&gt; e os cenários, o time teria de garantir que os testes de cada cenário estivessem passando.&lt;/p&gt;

&lt;p&gt;Essa ideia voltou à medida que o meu side project ia crescendo. O tempo de validar todas as features aumentava na mesma medida em que eu adicionava funcionalidades. A pergunta reapareceu: como consolidar o que tenho agora e garantir que eu possa adicionar coisas novas de forma estruturada, com testes que de fato validem o comportamento?&lt;/p&gt;

&lt;p&gt;BDD. Meu approach foi criar dois /commands no Cursor: um para gerar o .feature e outro para implementar a feature e seus testes.&lt;/p&gt;

&lt;h3&gt;
  
  
  /tony-bdd
&lt;/h3&gt;

&lt;p&gt;O comando pega um arquivo (um componente, uma rota, um handler) e extrai dele os cenários que importam. Em vez de organizar por página ou tela, organiza por domínio: auth, checkout, layout, o que fizer sentido pro vocabulário do código. Começa com poucos cenários de alto impacto, os journeys que provam que a coisa funciona ponta a ponta. Só depois, se precisar, desdobra em regras e variações. Cada cenário ganha um &lt;code&gt;@id&lt;/code&gt; estável. Um script varre os .feature e verifica se há teste correspondente a cada cenário declarado. Não usa Cucumber; os .feature são só a fonte de comportamento. O comando não toca em código nem em testes, só escreve specs.&lt;/p&gt;

&lt;h3&gt;
  
  
  /tony-bdd-test
&lt;/h3&gt;

&lt;p&gt;Já esse comando pega os cenários Gherkin e implementa os testes. Coloca os testes ao lado do código sob teste, com mocks mínimos (MSW quando for web). Para cada teste que escreve, exige um sanity-check por mutação: quebra a implementação de propósito, roda o teste, confirma que falha, reverte. O objetivo é garantir que os testes não passem por acaso.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tony-bdd (.feature) → tony-bdd-test (Testes) → Mutação → Teste falha? → (Sim → Reverte → Pronto) | (Não → Reforça → Mutação)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  /tony-workflow
&lt;/h3&gt;

&lt;p&gt;Os comandos base permitem criar .features e implementá-las. Como encadear os dois? É aí que entra o /tony-workflow. O workflow roda o /tony-bdd e depois o /tony-bdd-test, mas se aproveita da engenharia de contexto e subagents. Uma das instruções é paralelizar sempre que possível. Para features que lidam com partes diferentes do sistema ou que podem ser divididas em unidades de trabalho menores, uma vez gerados os .feature, cada um pode ser lançado em um subagent em paralelo, em background. Não bloqueia a thread principal nem polui o contexto principal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Thread principal: tony-bdd → .feature
                         ↓
    ┌────────────────────┼────────────────────┐
    ↓                    ↓                    ↓
Subagent 1          Subagent 2          Subagent N
    ↓                    ↓                    ↓
tony-bdd-test       tony-bdd-test       tony-bdd-test
    └────────────────────┼────────────────────┘
                         ↓
                    background
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Specs First vs BDD
&lt;/h3&gt;

&lt;p&gt;Então BDD é melhor que o spec first? Não. Na prática eles podem ser usados juntos. Você pode gerar a especificação (SpecKit, OpenSpec) e definir o que deve ser construído. Depois, esse spec vira insumo pro tony-bdd. Os cenários .feature nascem desse material. O spec diz o quê; o BDD extrai o comportamento testável.&lt;/p&gt;

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

&lt;p&gt;Essa metodologia não lida com ensinar ao agente como você quer que o código seja escrito. Ela cria ferramentas para garantir que, uma vez que o código está certo e validado, você não terá regressões ao longo do tempo. Esse workflow deve ser usado junto com outras técnicas: &lt;em&gt;skills&lt;/em&gt;, &lt;em&gt;rules&lt;/em&gt;, &lt;em&gt;guardrails&lt;/em&gt;, &lt;em&gt;agents.md&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Meu resultado: uma vez que o resultado está pronto e validado manualmente, revisar as interfaces criadas, os testes e a implementação leva menos tempo do que se eu tivesse que revisar tudo no Spec First. Por quê? Porque com tudo validado, testes prontos e implementação correta, posso trocar a implementação livremente. O que testo é a interface, não os detalhes internos. Isso me dá flexibilidade para refatorar sem medo pois está tudo coberto por testes. Se chegar ao ponto em que eu olho a implementação e percebo que não ficou tão boa quanto poderia ser; posso alterá-la completamente sabendo que os testes garantem o comportamento.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resultados
&lt;/h3&gt;

&lt;p&gt;Esses números vêm do projeto em que apliquei o workflow BDD. O coverage do Vitest cruza os cenários dos &lt;code&gt;.feature&lt;/code&gt; com os relatórios de cobertura; o valor 0 em Uncovered indica que todos os cenários têm ao menos algum teste associado; nenhum ficou sem cobertura.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Métrica&lt;/th&gt;
&lt;th&gt;Valor&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Arquivos de feature&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cenários BDD&lt;/td&gt;
&lt;td&gt;94&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Arquivos de teste&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Testes&lt;/td&gt;
&lt;td&gt;176&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coverage (Vitest)&lt;/td&gt;
&lt;td&gt;42%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Apesar de 42% ser uma cobertura baixa, a ideia não é ser exaustivo nos testes, mas preciso no que testar: garantir o comportamento que importa, não cobrir cada linha.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://x.com/effectfully/status/2029364333919060123" rel="noopener noreferrer"&gt;Tweet do @effectfully sobre agentes que dão um jeito de bypassar o teste&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://simonwillison.net/2026/Feb/23/agentic-engineering-patterns/" rel="noopener noreferrer"&gt;Writing about Agentic Engineering Patterns, Simon Willison&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://simonwillison.net/guides/agentic-engineering-patterns/red-green-tdd/" rel="noopener noreferrer"&gt;Red/green TDD, Simon Willison&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/pdf/2508.00083" rel="noopener noreferrer"&gt;A Survey on Code Generation with LLM-based Agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://x.com/onusoz/status/2027686423873073172/photo/1" rel="noopener noreferrer"&gt;Tweet do Onur Solmaz sobre documentar práticas e entender o estado da prática&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://x.com/neural_avb/status/2027721962479288566" rel="noopener noreferrer"&gt;A simple framework to build Agentic Systems that just works, @avb_fj&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cucumber.io/docs/bdd/" rel="noopener noreferrer"&gt;BDD, Cucumber&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stryker-mutator.io/" rel="noopener noreferrer"&gt;Stryker.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>tdd</category>
      <category>bdd</category>
    </item>
    <item>
      <title>My Agentic Engineering Process: From Vibe Code to BDD</title>
      <dc:creator>Antoniel Magalhães</dc:creator>
      <pubDate>Thu, 05 Mar 2026 15:38:05 +0000</pubDate>
      <link>https://dev.to/antoniel/my-agentic-engineering-process-from-vibe-code-to-bdd-2ne</link>
      <guid>https://dev.to/antoniel/my-agentic-engineering-process-from-vibe-code-to-bdd-2ne</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; I use BDD to turn specification into validated code. Scenarios define behavior; tests cover it; mutation checks that tests are actually useful. Once validated, I can refactor the implementation without fear of regression.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This post is about how I currently approach agentic engineering and how I try to build features using AI agents (Cursor, Claude Code, or any other) through a defined methodology—specifically BDD (Behavior Driven Design) to guide code production and ensure correctness.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vibe Code vs Agent Engineering
&lt;/h2&gt;

&lt;p&gt;The first time I saw the term agentic engineering was in &lt;a href="https://simonwillison.net/2026/Feb/23/agentic-engineering-patterns/" rel="noopener noreferrer"&gt;Simon Willison's article on agentic engineering patterns&lt;/a&gt;. I was already doing it, but kept calling it vibe coding; I liked the new name—it sounds more serious and well-defined.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vibe coding
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;When you don't pay attention to the code in general&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You don't pay attention to how things are being done. The focus is on shipping, not on establishing patterns or validating the quality of what the agent produces.&lt;/p&gt;

&lt;h3&gt;
  
  
  Agentic engineering
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;When you create and establish norms&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You create norms, guidelines, and define how you want the code to be written by the AI. You still don't type; but you actively influence how the code is produced.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploring new agentic engineering patterns
&lt;/h2&gt;

&lt;p&gt;Day to day, it's hard to give up productivity or quality relative to the baseline just to experiment with agentic engineering patterns. So what I usually do is create small side projects I want to build and use them to explore these capabilities with the agent.&lt;/p&gt;

&lt;p&gt;I started the project with my established agentic engineering workflow: I have an intention, I create a specification using SpecKit or OpenSpec, from the specification I create a plan, and from that plan I create the implementation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Intention → Specification → Plan → Implementation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A simple pipeline, but it works well for me. The "problem" is that I need to pay attention at every step: the intention is in my mind; I have to confirm the specification reflects what I imagined; verify the implementation plan follows what I imagined; and finally do code review of the implementation. This is a process that demands a lot of my attention, and I wanted to explore different patterns that could reduce my attention time per task while keeping the same quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  TDD
&lt;/h2&gt;

&lt;p&gt;I had already seen the pattern of using automated tests to validate the implementation and create that counterpressure on the agent so it validates its own work. I think it's valid. The problem, in my experience, is that when I let the agent create tests on its own, without adequate supervision, it ends up taking shortcuts: tests that cover trivial things and implementation details. Things like &lt;code&gt;expect(1).toBe(1)&lt;/code&gt; and the like.&lt;/p&gt;

&lt;p&gt;Simon documents the &lt;a href="https://simonwillison.net/guides/agentic-engineering-patterns/red-green-tdd/" rel="noopener noreferrer"&gt;red/green TDD pattern in his guide&lt;/a&gt;: make the test fail first, then make it pass, ensuring the test is actually useful. Given my experience, I still didn't feel comfortable trusting the agent's goodwill not to edit the test just to make it pass (&lt;a href="https://x.com/effectfully/status/2029364333919060123" rel="noopener noreferrer"&gt;@effectfully&lt;/a&gt;). My worst case: I implement TDD, spend &lt;code&gt;n&lt;/code&gt; minutes, go to review the code, specifically the tests, and the tests don't make sense—or I run a manual test and discover the feature doesn't work, yet the tests pass.&lt;/p&gt;

&lt;h3&gt;
  
  
  Before: Just Go
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Previous flow without formal specification&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Open the agent, explain the task, refine over iterations. No spec, no formal validation. The risk: trivial tests, implementation that passes but doesn't deliver what's expected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Explain task → Agent implements → Review → OK? → (No → Agent implements) | (Yes → Done)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  After: BDD
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Specification to action&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Spec → .feature → tony-bdd-test → mutation. Approved scenarios become the source of truth; tests validate behavior; mutation ensures tests don't pass by accident.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Spec → .feature → tony-bdd-test → Mutation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  BDD
&lt;/h2&gt;

&lt;p&gt;A while back, in pre-LLM times, I ran into a requirement: how to ensure code quality through tests that talk to the product? There was a gap between what was asked in the ticket and what the team delivered. The solution: BDD (Behavior Driven Design), &lt;a href="https://cucumber.io/docs/bdd/" rel="noopener noreferrer"&gt;documented by Cucumber&lt;/a&gt;. Once the &lt;code&gt;.feature&lt;/code&gt; files and scenarios were approved, the team would have to ensure the tests for each scenario were passing.&lt;/p&gt;

&lt;p&gt;That idea came back as my side project grew. The time to validate all features increased in step with the functionality I added. The question reappeared: how do I consolidate what I have now and ensure I can add new things in a structured way, with tests that actually validate behavior?&lt;/p&gt;

&lt;p&gt;BDD. My approach was to create two /commands in Cursor: one to generate the .feature and another to implement the feature and its tests.&lt;/p&gt;

&lt;h3&gt;
  
  
  /tony-bdd
&lt;/h3&gt;

&lt;p&gt;The command takes a file (a component, a route, a handler) and extracts the scenarios that matter from it. Instead of organizing by page or screen, it organizes by domain: auth, checkout, layout, whatever makes sense for the code's vocabulary. It starts with few high-impact scenarios, the journeys that prove the thing works end-to-end. Only later, if needed, it unfolds into rules and variations. Each scenario gets a stable &lt;code&gt;@id&lt;/code&gt;. A script sweeps the .feature files and checks that there's a corresponding test for each declared scenario. It doesn't use Cucumber; the .feature files are just the behavior source. The command doesn't touch code or tests, it only writes specs.&lt;/p&gt;

&lt;h3&gt;
  
  
  /tony-bdd-test
&lt;/h3&gt;

&lt;p&gt;This command takes the Gherkin scenarios and implements the tests. It places tests next to the code under test, with minimal mocks (MSW when it's web). For each test it writes, it requires a sanity-check by mutation: break the implementation on purpose, run the test, confirm it fails, revert. The goal is to ensure tests don't pass by accident.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tony-bdd (.feature) → tony-bdd-test (Tests) → Mutation → Test fails? → (Yes → Revert → Done) | (No → Reinforce → Mutation)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  /tony-workflow
&lt;/h3&gt;

&lt;p&gt;The base commands allow creating .features and implementing them. How to chain the two? That's where /tony-workflow comes in. The workflow runs /tony-bdd and then /tony-bdd-test, but leverages context engineering and subagents. One of the instructions is to parallelize whenever possible. For features that touch different parts of the system or can be split into smaller work units, once the .feature files are generated, each can be launched in a subagent in parallel, in the background. It doesn't block the main thread nor pollute the main context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Main thread: tony-bdd → .feature
                    ↓
    ┌───────────────┼───────────────┐
    ↓               ↓               ↓
Subagent 1      Subagent 2      Subagent N
    ↓               ↓               ↓
tony-bdd-test  tony-bdd-test   tony-bdd-test
    └───────────────┼───────────────┘
                    ↓
               background
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Specs First vs BDD
&lt;/h3&gt;

&lt;p&gt;So is BDD better than spec first? No. In practice they can be used together. You can generate the specification (SpecKit, OpenSpec) and define what should be built. Then that spec becomes input for tony-bdd. The .feature scenarios are born from that material. The spec says what; BDD extracts the testable behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This methodology doesn't deal with teaching the agent how you want the code to be written. It creates tools to ensure that, once the code is correct and validated, you won't have regressions over time. This workflow should be used together with other techniques: &lt;em&gt;skills&lt;/em&gt;, &lt;em&gt;rules&lt;/em&gt;, &lt;em&gt;guardrails&lt;/em&gt;, &lt;em&gt;agents.md&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;My result: once the outcome is ready and manually validated, reviewing the created interfaces, tests, and implementation takes less time than if I had to review everything in Spec First. Why? Because with everything validated, tests in place, and correct implementation, I can change the implementation freely. What I test is the interface, not the internals. That gives me flexibility to refactor without fear since it's all covered by tests. If I reach the point where I look at the implementation and see it's not as good as it could be, I can change it completely knowing the tests guarantee the behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  Results
&lt;/h3&gt;

&lt;p&gt;These numbers come from the project where I applied the BDD workflow. Vitest coverage crosses the &lt;code&gt;.feature&lt;/code&gt; scenarios with coverage reports; the 0 in Uncovered indicates that all scenarios have at least one associated test; none were left without coverage.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Feature files&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BDD scenarios&lt;/td&gt;
&lt;td&gt;94&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test files&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tests&lt;/td&gt;
&lt;td&gt;176&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coverage (Vitest)&lt;/td&gt;
&lt;td&gt;42%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Although 42% is low coverage, the idea isn't to be exhaustive in tests, but precise in what to test: ensure the behavior that matters, not cover every line.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://x.com/effectfully/status/2029364333919060123" rel="noopener noreferrer"&gt;@effectfully tweet on agents that find ways to bypass the test&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://simonwillison.net/2026/Feb/23/agentic-engineering-patterns/" rel="noopener noreferrer"&gt;Writing about Agentic Engineering Patterns, Simon Willison&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://simonwillison.net/guides/agentic-engineering-patterns/red-green-tdd/" rel="noopener noreferrer"&gt;Red/green TDD, Simon Willison&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/pdf/2508.00083" rel="noopener noreferrer"&gt;A Survey on Code Generation with LLM-based Agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://x.com/onusoz/status/2027686423873073172/photo/1" rel="noopener noreferrer"&gt;Onur Solmaz tweet on documenting practices and understanding the state of practice&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://x.com/neural_avb/status/2027721962479288566" rel="noopener noreferrer"&gt;A simple framework to build Agentic Systems that just works, @avb_fj&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cucumber.io/docs/bdd/" rel="noopener noreferrer"&gt;BDD, Cucumber&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stryker-mutator.io/" rel="noopener noreferrer"&gt;Stryker.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>bdd</category>
      <category>testing</category>
    </item>
    <item>
      <title>Entendendo useState e useReducer</title>
      <dc:creator>Antoniel Magalhães</dc:creator>
      <pubDate>Mon, 01 Feb 2021 22:08:27 +0000</pubDate>
      <link>https://dev.to/antoniel/entendendo-usestate-e-usereducer-32i9</link>
      <guid>https://dev.to/antoniel/entendendo-usestate-e-usereducer-32i9</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;O estado  em uma aplicação react é um faz parte dos conceitos fundamentais da biblioteca, desde a adoção dos hooks na versão 16.8 temos dois hooks que tem a função de lidar com estados, o useState e o useReducer. Nesse post eu vou tentar dar uma breve explicação sobre cada um dos hooks e suas particularidades;&lt;/p&gt;

&lt;h1&gt;
  
  
  useState
&lt;/h1&gt;

&lt;p&gt;De acordo com @types/react o hook useState possui a seguinte tipagem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;S&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;S&lt;/span&gt; &lt;span class="o"&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="nx"&gt;S&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;S&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Dispatch&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SetStateAction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;S&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;O useState recebe um parâmetro, o initialState&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Esse parâmetro pode ser um valor do tipo S ou uma função que retorna o tipo S, que é um &lt;code&gt;tipo genérico&lt;/code&gt; ou seja, assume o tipo do seu estado, podendo ser um numero, string, ou um objeto qualquer.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;O useState retorna uma array de duas posições&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;S se refere ao estado atual&lt;/li&gt;
&lt;li&gt;Dispatch&amp;gt; é a função que vai atualizar aquele componente, o dispatch pode receber o valor que o estado vai ser atualizado ou um callback do tipo &lt;code&gt;((prevState: S) =&amp;gt; S);&lt;/code&gt; recebendo o estado anterior e retornando o estado atual.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h1&gt;
  
  
  useReducer
&lt;/h1&gt;

&lt;p&gt;Ainda de acordo com @types/react o hook useReducer possui a seguinte tipagem,A estrutura básica do useReducer é uma função que recebe entre 2 e 3 parâmetros e retorna um array de duas posições:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useReducer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;R&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Reducer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;I&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;                                  
            &lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                                                                       
            &lt;span class="nx"&gt;initializerArg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;I&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                                                                
            &lt;span class="nx"&gt;initializer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;I&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;ReducerState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="o"&gt;&amp;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;ReducerState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Dispatch&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ReducerAction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;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;ul&gt;
&lt;li&gt;Os parâmetros do useReducer:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Reducer é um callback com a seguinte estrutura: &lt;code&gt;(prevState: S, action: A) =&amp;gt; S;&lt;/code&gt;, esse callback é o responsável por atualizar o estado, seria o equivalente ao SetStateAction do useState, porém com suas particularidades, a exemplo o parâmetro do callback, o action, nele é possível definir o tipo da ação, passar dados através do payload, o reducer deve ficar mais claro durante os exemplos. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;O initializerArg assim como initialState do useState é o parâmetro que vai receber o estado inicial do estado.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;O &lt;code&gt;initializer&lt;/code&gt;, esse recebe uma função responsável por modificar o initializeArg durante a montagem do componente modificando o estado inicial do reducer.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;O useReducer retorna um array com 2 parâmetros: &lt;code&gt;[ReducerState&amp;lt;R&amp;gt;, Dispatch&amp;lt;ReducerAction&amp;lt;R&amp;gt;&amp;gt;]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;O primeiro parâmetro é o State do useReducer&lt;/li&gt;
&lt;li&gt;O segundo parâmetro é a função que vai chamar o reducer (1º parâmetro do useReducer), recebendo parâmetro action, onde no retorno do reducer o state é atualizado.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Exemplos
&lt;/h1&gt;

&lt;p&gt;partindo do caso de uso que o nosso estado é uma lista de jogadores, como podemos modificar essa lista utilizando o useState e o useReducer.&lt;/p&gt;

&lt;h2&gt;
  
  
  useState
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* No caso do useState se quisermos alterar esse estado em um componente abaixo podemos passar o setPlayer como prop. e montar o callback no componente abaixo, ou montar o addPlayer e passa-lo como prop. */&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;players&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPlayers&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialState&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;addPlayer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newPlayer&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;setPlayers&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;players&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newPlayer&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// Como o setPlayers vai ser chamado 👇&lt;/span&gt;
&lt;span class="nf"&gt;addPlayers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Ronaldo&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;
  
  
  useReducer
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* Com o useReducer uma vez que defnimos a função reducer e suas ações passamos simplesmente o dispatch para baixo na arvore de componentes e cada componente chama a sua respectiva ação */&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reducer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&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;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;addPlayer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&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;newState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;players&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useReducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initialArg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Como o reducer vai ser chamado 👇&lt;/span&gt;
&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;addPlayer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;payload&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ronaldo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Os dois códigos acima fazer a exatamente a mesma coisa, o useReducer parece muito mais verboso e compelxo que o useState, quais suas vantagens ? imagine uma situação que muitos outros métodos, adicionar, remover, atualizar... e ainda com outros estados como estado de loading, error entre outros. Como fariamos essas outras funções acessíveis para os componentes que a consomem ? criariamos uma nova prop para cada função, até setia possível mas imagina o caos que não seri esse componente, o useReducer aparece nesses casos onde você precisa lidar com muitos métodos e estados de um componente, a função reducer poderia ficar em um arquivo separado aumentando a qualidade e legibilidade do código, você saberia exatamente em qual tipo de action modificar, e ao invés de passar cada método com uma nova prop você pode passar só o dispatch e cada componente chama o tipo de ação que precisar.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Quando você precisa lidar com apenas um estado, é mais simples conveniente utilizar o useState ao invés do use Reducer  apenas um estado para &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://reactjs.org/docs/hooks-reference.html#usereducer" rel="noopener noreferrer"&gt;React Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>typescript</category>
      <category>ptbr</category>
    </item>
    <item>
      <title>Consumindo uma API no React</title>
      <dc:creator>Antoniel Magalhães</dc:creator>
      <pubDate>Mon, 01 Feb 2021 02:04:20 +0000</pubDate>
      <link>https://dev.to/antoniel/consumindo-uma-api-no-react-2ea5</link>
      <guid>https://dev.to/antoniel/consumindo-uma-api-no-react-2ea5</guid>
      <description>&lt;h1&gt;
  
  
  Contexto
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;O código dessa aplicação está nesse &lt;a href="https://github.com/antoniel/breaking-bad-characters" rel="noopener noreferrer"&gt;link&lt;/a&gt;, o resultado final se encontra &lt;a href="http://breaking-bad-characters-git-main.antonielmagalhaes.vercel.app/" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Uma duvida muito comum quando se inicia no desenvolvimento web é como fazer aplicações o backend e o frontend se comunicarem. Como que eu posso fazer minha aplicação react se comunicar com minha API ? Essas são as dúvidas que eu vou tentar responder brevemente com esse post.&lt;/p&gt;

&lt;h1&gt;
  
  
  Como ?
&lt;/h1&gt;

&lt;p&gt;A comunicação entre essas partes do sistema pode ser feita a partir do método http, que é um protocolo de comunicação onde através dele é possível a comunicação entre os diferentes pontos de um sistema. O protocolo Http possui métodos que são utilizados para diferentes finalidades, os principais são o GET e o POST, explicando de forma mínima o GET teria a função de pegar dados do servidor enquanto o POST teria a função de transmitir dados para o servidor.&lt;/p&gt;

&lt;h1&gt;
  
  
  Como eu faço isso em uma aplicação React
&lt;/h1&gt;

&lt;p&gt;O Código abaixo é uma função javascript que vai receber o nome de uma personagem e vai fazer uma requisição para para a api retornar os personagens que coincidem com aqueles nomes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchCharacters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;charactersName&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`https://www.breakingbadapi.com/api/characters/?name=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;charactersName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na primeira linha há uma requisição é feita a requisição para o a rota &lt;code&gt;api/characters/&lt;/code&gt; passando o parâmetro &lt;code&gt;name&lt;/code&gt; que vai receber o parâmetro da função, a constante response vai receber uma Promise de uma resposta http, para extrair os dados dessa resposta utilizamos na proxima linha o método &lt;code&gt;.json()&lt;/code&gt; que também é um Promise só que agora da resposta do servidor com o nome do personagem, apelido... &lt;/p&gt;

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

&lt;p&gt;No caso da minha aplicação essa função é chamada ao enviar do formulário que pergunta o nome do personagem da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&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;inputValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;value&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;charachtersData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchCharacters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;setCharacters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;charachtersData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSubmit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A primeira linha da função handleSubmit vai evitar que a página recarregue por conta do comportamento padrão do elemento form, o inputValue armazena o nome do personagem pesquisado, o charachtersData vai armazenar a resultado da função que foi apresentada anteriormente, e por último a reposta da api é definida como estado pelo setCharacters, agora é só exibir esses dados como queira.&lt;/p&gt;

&lt;p&gt;Uma outra forma de fazer essa requisição é quando o componente é montado, digamos que você quer exibir as informações do Walter White enquanto o usuário não escolhe o personagem, você pode ter pensado em fazer da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SearchBar&lt;/span&gt; &lt;span class="o"&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="nx"&gt;cosnt&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCharacters&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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="nf"&gt;fetchCharacters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Walter White&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;setCharacters&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/*Componentes do formulário*/&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se feito dessa forma, você vai ter um problema desse componente ser renderizado infinitamente pois, como ele atualiza o estado do componente, ele força que o componente remonte, e durante o processo de montagem ele vai novamente fazer a requisição e assim por diante... &lt;/p&gt;

&lt;p&gt;Para fazer essa requisição enquanto o componente monta é necessário utilizar o hook useEffect, /&lt;em&gt;UTILIZANDO ARRAY DE DEPENDÊNCIAS&lt;/em&gt;/&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SearchBar&lt;/span&gt; &lt;span class="o"&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="nx"&gt;cosnt&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCharacters&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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="nf"&gt;useEffect&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;fetchCharacters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Walter White&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;setCharacters&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="p"&gt;[])&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/*Componentes do formulário*/&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa forma toda vez que o componente SearchBar for montado a função fetchCharacters vai ser chamada e seu retorno passado para o setCharacters que vai modificar o estado.&lt;/p&gt;

&lt;p&gt;Essas são as formas de comunicação http através do React, a partir da montagem do componente ou através de um evento como o enviar do formulário.&lt;/p&gt;

</description>
      <category>react</category>
      <category>api</category>
      <category>http</category>
      <category>ptbr</category>
    </item>
    <item>
      <title>Docker basic concepts</title>
      <dc:creator>Antoniel Magalhães</dc:creator>
      <pubDate>Thu, 27 Aug 2020 02:58:51 +0000</pubDate>
      <link>https://dev.to/antoniel/docker-basic-concepts-1902</link>
      <guid>https://dev.to/antoniel/docker-basic-concepts-1902</guid>
      <description>&lt;p&gt;Docker helps us to manage the services of our applications (Databases or another external service). We can use to create isolated systems in our machine, this means a service doesn't interfere in other services or in our server. The services in our machine are called by images, images are services available to us,  containers are instances of these services, are isolated of the rest of our server, containers expose one port to communicate with our machine, we communicate with a container mapping one port of our machine to one port of container, then we have a way to communicate with container.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to install a new image on docker
&lt;/h2&gt;

&lt;p&gt;Firstly we define which service we use on our application, in this case I will use Postgres. Searching for Postgres Image on google we find the site called by &lt;a href="https://hub.docker.com/_/postgres" rel="noopener noreferrer"&gt;https://hub.docker.com/_/postgres&lt;/a&gt; , there you can find a more detailed tutorial, but basically is possible to download a docker image with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--name&lt;/span&gt; database &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;docker &lt;span class="nt"&gt;-p&lt;/span&gt; 5432:5432 &lt;span class="nt"&gt;-d&lt;/span&gt; postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Analizing each pice of the comand above, we got:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;docker run ⇒ Create and start a new container with the specify image.&lt;/li&gt;
&lt;li&gt;—name database ⇒ Setting a name to our container.&lt;/li&gt;
&lt;li&gt;-e POSTGRES_PASSWORD=docker ⇒ Setting environment variables, postgres_password is required for you to use the PostgreSQL image.&lt;/li&gt;
&lt;li&gt;-p 5432:5432 ⇒ Mapping [Host port] : [Container port]&lt;/li&gt;
&lt;li&gt;-d ⇒ Start container in background&lt;/li&gt;
&lt;li&gt;postgres ⇒ Name of the image&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After creating our container, how if all is working as we expected? The command docker ps, show all containers running at the moment. If you want to see all containers instead only running you do it using docker ps -a.&lt;/p&gt;

&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;p&gt;&lt;a href="http://dockerlabs.collabnix.com/docker/cheatsheet/" rel="noopener noreferrer"&gt;http://dockerlabs.collabnix.com/docker/cheatsheet/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hub.docker.com/_/postgres" rel="noopener noreferrer"&gt;https://hub.docker.com/_/postgres&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>database</category>
      <category>100daysofcode</category>
    </item>
    <item>
      <title>How to set up Nodemon &amp; Sucrase</title>
      <dc:creator>Antoniel Magalhães</dc:creator>
      <pubDate>Wed, 26 Aug 2020 04:54:34 +0000</pubDate>
      <link>https://dev.to/antoniel/how-to-set-up-nodemon-sucrase-31ic</link>
      <guid>https://dev.to/antoniel/how-to-set-up-nodemon-sucrase-31ic</guid>
      <description>&lt;h2&gt;
  
  
  What is Sucrase?
&lt;/h2&gt;

&lt;p&gt;Sucrase let us develop Node app in ES6,is an alternative to Babel that allows super-fast development builds. If it fits your use case, hopefully, Sucrase can speed up your development experience!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Nodemon?
&lt;/h2&gt;

&lt;p&gt;Nodemon is a tool that helps develop node.js based applications by automatically restarting the node application when file changes in the directory are detected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Start
&lt;/h2&gt;

&lt;p&gt;First you need to install the packages as development dependencies,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add &lt;span class="nt"&gt;--dev&lt;/span&gt; sucrase 
yarn add &lt;span class="nt"&gt;--dev&lt;/span&gt; nodemon
&lt;span class="c"&gt;# Or &lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; sucrase
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; nodemon
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After setting the packages as project dependencies, if we try to use the features of Sucrase like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node index.js
&lt;span class="c"&gt;#Or&lt;/span&gt;
nodemon index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will encounter an error because to compile with sucrase, is necessary use sucrase-node instead node, on use nodemon node is called every time some file change in a directory, so how we set to nodemon use sucrase-node instead node? &lt;/p&gt;

&lt;h2&gt;
  
  
  Nodemon + Sucrase
&lt;/h2&gt;

&lt;p&gt;To set Nodemon to use sucrase we need to create a file nodemon.json in our '/' project, with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"execMap"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"js"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node -r sucrase/register"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we create this file every time nodemon executes a js file, it will be compiled by sucrase before run the code.&lt;/p&gt;

&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/sucrase" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/sucrase&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/nodemon" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/nodemon&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>100daysofcode</category>
      <category>nodemon</category>
      <category>sucrase</category>
    </item>
    <item>
      <title>Tipos de parâmetros em requisições em http</title>
      <dc:creator>Antoniel Magalhães</dc:creator>
      <pubDate>Thu, 20 Aug 2020 01:20:42 +0000</pubDate>
      <link>https://dev.to/antoniel/tipos-de-parametros-em-requisicoes-em-http-2i2o</link>
      <guid>https://dev.to/antoniel/tipos-de-parametros-em-requisicoes-em-http-2i2o</guid>
      <description>&lt;p&gt;Existem 3 tipos de parâmetros &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Query params&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;São os parâmetros de consulta &lt;em&gt;(query parms)&lt;/em&gt; aparecem da seguinte forma: dominio.com/?cidade=salvador.&lt;/p&gt;

&lt;p&gt;Esse parâmetros pode ser acessados por:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="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="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;cidade&lt;/span&gt; &lt;span class="o"&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;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cidade&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cidade&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;// Retorna: "salvador"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Route params&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Os parâmetros de rota &lt;em&gt;(routes params)&lt;/em&gt; aparecem da seguinte forma: dominio.com/usuario/22&lt;/p&gt;

&lt;p&gt;Esse parâmetros pode ser acessados por:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/usuario/:id&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;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="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;id&lt;/span&gt; &lt;span class="o"&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;parms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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="c1"&gt;// Retorna: "salvador"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Request body&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Diferente dos parâmetros anteriores, o body mão fica visível na url, os dados são transmitidos através do método POST.&lt;/p&gt;

&lt;p&gt;Esse parâmetros pode ser acessados por:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Usiario0&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;Usuario1&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;Usuario2&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/usuario/&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;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="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;id&lt;/span&gt; &lt;span class="o"&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;body&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="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="c1"&gt;// Retorna: "salvador"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Primeiros passos com TypeScript</title>
      <dc:creator>Antoniel Magalhães</dc:creator>
      <pubDate>Thu, 20 Aug 2020 01:07:43 +0000</pubDate>
      <link>https://dev.to/antoniel/fundamentos-do-typescript-noa</link>
      <guid>https://dev.to/antoniel/fundamentos-do-typescript-noa</guid>
      <description>&lt;h1&gt;
  
  
  O que é TypeScript
&lt;/h1&gt;

&lt;p&gt;O TypeScript não é uma nova linguagem, ele pode ser definido como um superset do javascript, ou seja um javascript "melhorado", isso significa que os códigos que são válidos em javascript também são válidos em typescript, TypeScript possui funcionalidades/features adicionais que o js tradicional não traz suporte ainda. Os browsers também não compreendem o typescript, portanto é necessário um transpilador entre ele e o browser. Esse transpilador vai re-escrever o código de forma que os browsers consigam compreender.&lt;/p&gt;

&lt;h3&gt;
  
  
  TypeScript features:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Tipagem forte&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quando definimos uma variável precisamos especificar qual o seu tipo, há casos que o tipo é identificado sem a necessariamente ser declarado. Utilizar essa funcionalidade torna o código mais previsível e mais fácil de encontrar bugs caso algo dê errado.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Erros em tempo de compilação&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Isso permite que seja possível visualizar os erros em tempo de compilação e não somente em tempo de execução, diante disso é possível fixar esses erros antes de iniciar o programa.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Great tooling&lt;/p&gt;

&lt;p&gt;Isso permite que a intellisense dos editores de texto consiga prever com maior facilidade os tipos das variáveis que estão sendo trabalhadas.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Start
&lt;/h2&gt;

&lt;p&gt;Inicialmente é necessário instalar o typescript globalmente em nossa máquina, utilizando o gerenciador de pacotes da sua preferência, yarn ou npm.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Instalando typescript&lt;/span&gt;
&lt;span class="nx"&gt;ts&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="err"&gt;⇒&lt;/span&gt; &lt;span class="nx"&gt;yarn&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="nx"&gt;typescript&lt;/span&gt;
&lt;span class="c1"&gt;// Verificando versão&lt;/span&gt;
&lt;span class="nx"&gt;ts&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="err"&gt;⇒&lt;/span&gt; &lt;span class="nx"&gt;tsc&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;
&lt;span class="nx"&gt;Version&lt;/span&gt; &lt;span class="mf"&gt;3.9&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="c1"&gt;// Criando o arquivo em que vamos trabalhar&lt;/span&gt;
&lt;span class="nx"&gt;ts&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="err"&gt;⇒&lt;/span&gt; &lt;span class="nx"&gt;touch&lt;/span&gt; &lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Tipos em TypeScript
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Declarando tipos
&lt;/h3&gt;

&lt;p&gt;Na maioria das vezes o próprio typescript consegue inferir qual o tipo de cada variável, apenas em momentos específicos os tipos necessitam ser explicitamente declarados. Os diferentes tipos em Ts são:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&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;A&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Type Assertions
&lt;/h3&gt;

&lt;p&gt;Para variáveis iniciadas com o valor any, o ts não reconhece qual seus métodos os type assertions são formas de informar, de informar quais o tipo daquela variável após sua inicialização. Type Assertion é unicamente uma forma de dizer ao compilador ts qual a o tipo daquela variável e dessa forma podermos acessa a intellisense.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;abc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;alternativeWay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;endsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;c&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;endsWithC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;message).endsWith('c')

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Custom types in TypeScript
&lt;/h3&gt;

&lt;p&gt;Nesse caso em específico nossa função tem apenas dois parâmetros mas existem situações em que trabalhando com situações mais complexas é possível ter diversos parâmetros, nessas situações é usual agrupar todos esses parâmetro em um único parâmetro como no parâmetro a seguir.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/*Situação problemática*/&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;drawPoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;point&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="c1"&gt;//Suponhamos um algorítimo que vai desenhar na tela&lt;/span&gt;
    &lt;span class="c1"&gt;//e precisa das cordenadas x e y&lt;/span&gt;
    &lt;span class="c1"&gt;//Acessadas por point.x, point.y&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;drawPoint&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na situação acima caso o objeto que seja passado não tenha as chaves e valores esperados pela função há grandes chances de que esse programa quebre durante o tempo de execução. Uma forma de prevenir essa situação é passar a custom type para esse parâmetro da seguinte forma.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/*Situação resolvida*/&lt;/span&gt;
&lt;span class="cm"&gt;/*Inline Notation*/&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;drawPoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;point&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/*Situação resolvida*/&lt;/span&gt;
&lt;span class="cm"&gt;/*Utilizando Interfaces*/&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;drawPoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;point&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Point&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="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Acima temos as duas abordagens de custom types, &lt;strong&gt;inline Notation&lt;/strong&gt; e utilizando &lt;strong&gt;interfaces&lt;/strong&gt;, utilizar interfaces leva certa vantagem sobre o inline pois tem uma abordagem mais limpa, em caso de muitos parâmetros a primeira pode se tornar confusa, além do fato de que as interfaces podem ser reutilizadas em diversos lugares.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>tutorial</category>
      <category>firstyearincode</category>
      <category>100daysofcode</category>
    </item>
  </channel>
</rss>
