<?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: Natanael Alves</title>
    <description>The latest articles on DEV Community by Natanael Alves (@eunael).</description>
    <link>https://dev.to/eunael</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%2F2060801%2F11610679-2d5f-4c48-aa79-07aada45dd7b.jpg</url>
      <title>DEV Community: Natanael Alves</title>
      <link>https://dev.to/eunael</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eunael"/>
    <language>en</language>
    <item>
      <title>Implementando MongoDB no Symfony</title>
      <dc:creator>Natanael Alves</dc:creator>
      <pubDate>Sat, 01 Feb 2025 19:03:33 +0000</pubDate>
      <link>https://dev.to/eunael/implementando-mongodb-no-symfony-2mob</link>
      <guid>https://dev.to/eunael/implementando-mongodb-no-symfony-2mob</guid>
      <description>&lt;p&gt;Eaí! Estava estudando mais sobre NoSQL com o MongoDB e decidi implementar o Mongo como banco de dados na API de um projeto que eu havia feito anteriormente com o Symfony.&lt;/p&gt;

&lt;p&gt;Explicando rapidamente o projeto: é um compartilhador de arquivos. O usuário envia um arquivo e recebe um link de compartilhamento. Assim, qualquer pessoa com acesso a esse link pode visualizar o arquivo.&lt;/p&gt;

&lt;p&gt;Nesse fluxo do projeto, o Mongo será utilizado para armazenar dados importantes do arquivo enviado pelo usuário, como id, nome, extensão e data de upload. Quando alguém acessar o link de compartilhamento, a API poderá recuperar o arquivo do serviço onde está armazenado (no caso, o Cloudflare R2) e retornar o arquivo correto para o usuário.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requisitos
&lt;/h2&gt;

&lt;p&gt;Antes de trabalhar com o Mongo no projeto, precisamos preparar o PHP para dar suporte ao Mongo. Para isso, a própria documentação do PHP tem instruções de como fazer isso: &lt;a href="https://www.php.net/manual/en/mongodb.installation.php" rel="noopener noreferrer"&gt;https://www.php.net/manual/en/mongodb.installation.php&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Também precisamos de um servidor com o Mongo rodando. Existem várias formas de obter isso, e eu utilizei um serviço do próprio Mongo chamado MongoDB Atlas Cluster, que possui um tier gratuito para testes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Importante
&lt;/h2&gt;

&lt;p&gt;A implementação do Mongo em um projeto Symfony é bem simples, mas existem algumas considerações importantes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Não existe mais &lt;code&gt;ORM&lt;/code&gt;, agora é &lt;code&gt;ODM&lt;/code&gt; (sigla para Object-Document Mapper)&lt;/li&gt;
&lt;li&gt;Por isso, não existe &lt;code&gt;EntityManager&lt;/code&gt;, agora é &lt;code&gt;DocumentManager&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Enfim, não existem mais Entidades, agora são Documentos, assim, criamos os documentos na pasta &lt;code&gt;src/Document&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Agora sim, vamos para a implementação.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Instale o módulo do mongo no projeto&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="n"&gt;composer&lt;/span&gt; &lt;span class="k"&gt;require&lt;/span&gt; &lt;span class="n"&gt;doctrine&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mongodb&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;odm&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bundle&lt;/span&gt;
&lt;span class="c1"&gt;# Do you want to execute this recipe? 'yes'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Em &lt;code&gt;config/packages/doctrine_mongodb.yaml&lt;/code&gt;, apague tudo e cole&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="n"&gt;doctrine_mongodb&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;auto_generate_proxy_classes&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="n"&gt;auto_generate_hydrator_classes&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="n"&gt;connections&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"%env(resolve:MONGODB_URL)%"&lt;/span&gt;
  &lt;span class="n"&gt;default_database&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"%env(resolve:MONGODB_DB)%"&lt;/span&gt;
  &lt;span class="n"&gt;document_managers&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;auto_mapping&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="n"&gt;mappings&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="nc"&gt;App&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"%kernel.project_dir%/src/Document"&lt;/span&gt;
          &lt;span class="n"&gt;mapping&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
          &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attribute&lt;/span&gt;
          &lt;span class="n"&gt;prefix&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'App\Document'&lt;/span&gt;
          &lt;span class="n"&gt;is_bundle&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
          &lt;span class="n"&gt;alias&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Crie as variáveis de ambiente &lt;code&gt;MONGODB_URL&lt;/code&gt; e &lt;code&gt;MONGODB_DB&lt;/code&gt;, depois coloque respectivamente a conexão com seu servidor MongoDB e o nome do Database que você criou para o projeto. Também comentei a conexão do &lt;code&gt;sqlite&lt;/code&gt; que havia antes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Crie os documentos do seu projeto. É bem parecido com criar uma entidade, exceto que:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Invés de ORM é ODM&lt;/li&gt;
&lt;li&gt;Invés de "table" é "colletion"&lt;/li&gt;
&lt;li&gt;Invés de "Entity" é "Document"&lt;/li&gt;
&lt;li&gt;Invés de "Column" é "Field"&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Meu exemplo:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Document&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Doctrine\ODM\MongoDB\Mapping\Annotations&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="no"&gt;ODM&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="na"&gt;#[ODM\Document(collection: 'files')]&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;#[ODM\Id]&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;?string&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="na"&gt;#[ODM\Field]&lt;/span&gt;
      &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;?string&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;#[ODM\Field]&lt;/span&gt;
      &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;?int&lt;/span&gt; &lt;span class="nv"&gt;$size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;#[ODM\Field]&lt;/span&gt;
      &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;?string&lt;/span&gt; &lt;span class="nv"&gt;$type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;#[ODM\Field]&lt;/span&gt;
      &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;?string&lt;/span&gt; &lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="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;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;?string&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Crie o repository do documento&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Repository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Document\File&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Doctrine\Bundle\MongoDBBundle\ManagerRegistry&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Doctrine\Bundle\MongoDBBundle\Repository\ServiceDocumentRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FileRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ServiceDocumentRepository&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ManagerRegistry&lt;/span&gt; &lt;span class="nv"&gt;$registry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$registry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;File&lt;/span&gt; &lt;span class="nv"&gt;$entity&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;File&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getDocumentManager&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;persist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$entity&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getDocumentManager&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;flush&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$entity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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




&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Onde utilizava &lt;code&gt;App\Entity\File&lt;/code&gt; troque para &lt;code&gt;App\Document\File&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;A utilização do document para inserir, atualizar etc. é a mesma como era com as entidades. Pode ver um exemplo no método &lt;code&gt;upload&lt;/code&gt; do &lt;code&gt;FileController&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="nv"&gt;$file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$fileDTO&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$fileDTO&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$fileDTO&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$fileKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;fileRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Agora é só testar&lt;/p&gt;&lt;/li&gt;

&lt;/ol&gt;

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

&lt;p&gt;Decidi utilizar o Mongo neste projeto mais por estudo. Tanto as tecnologias SQL quanto NoSQL serviriam para este projeto. No entanto, cada caso é um caso. É necessário avaliar qual tipo de banco é mais adequado para resolver o problema em questão. Às vezes os bancos relacionais são a opção certa, outras vezes armazenar em documentos é melhor. DEPENDE.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Minha experiência com Symfony e Angular</title>
      <dc:creator>Natanael Alves</dc:creator>
      <pubDate>Sun, 26 Jan 2025 13:56:17 +0000</pubDate>
      <link>https://dev.to/eunael/minha-experiencia-com-symfony-e-angular-32il</link>
      <guid>https://dev.to/eunael/minha-experiencia-com-symfony-e-angular-32il</guid>
      <description>&lt;p&gt;Há algum tempo, tenho feito um ciclo de estudos para conhecer ferramentas além das do meu dia a dia. Nesse processo, estou me familiarizando com o framework Symfony do PHP e estudando o framework Angular para front-end, além de outras tecnologias.&lt;/p&gt;

&lt;p&gt;Essas duas ferramentas me chamaram muito a atenção pois, apesar de compartilharem vários conceitos com o Laravel e o Vue (minha stack atual), as preocupações durante o desenvolvimento são um pouco diferentes.&lt;br&gt;
Um exemplo para mim é que no Symfony senti uma necessidade maior de aplicar os princípios do SOLID (principalmente o "D") do que no Laravel. Isso não é necessariamente ruim — pelo contrário. Enquanto no Laravel muitos processos são abstraídos a ponto de parecerem "mágicos", no Symfony percebi que tenho mais controle sobre a aplicação. Como sou eu quem cria a estrutura do projeto, sei exatamente o que cada método faz e como faz.&lt;/p&gt;

&lt;p&gt;No Angular, apesar de achar verboso, utilizar o paradigma Orientado à Objetos permitiu que a minha imersão no framework foi mais ágil, pois só precisa declarar as propriedades e métodos que preciso na classe e usar; se precisar algum comportamento diferente, basta adicionar um decorator que resolve. Mas não que a abordagem de outros frameworks sejam ruim.&lt;/p&gt;

&lt;p&gt;Enfim, essa é minha perspectiva após sair da minha “bolha” e experimentar ferramentas novas além das que estou habituado. Estou estudando também sobre outro assuntos, como mensageria, NoSQL, observalidade… está sendo uma experiência dahora.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Quatro palavras da mensageria</title>
      <dc:creator>Natanael Alves</dc:creator>
      <pubDate>Sun, 26 Jan 2025 13:46:11 +0000</pubDate>
      <link>https://dev.to/eunael/quatro-palavras-da-mensageria-6ep</link>
      <guid>https://dev.to/eunael/quatro-palavras-da-mensageria-6ep</guid>
      <description>&lt;p&gt;As quatro palavras fundamentais quando falamos de mensageria são: &lt;strong&gt;Producer, Exchange, Queue e Consumer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Para facilitar a compreensão, vamos usar um exemplo real de e-commerce, que envolve vários serviços como recebimento de pedidos, processamento de pagamentos, atualização de estoque, notificação ao cliente e logística de entregas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Producer:
&lt;/h2&gt;

&lt;p&gt;É quem inicia a comunicação entre os serviços. No nosso exemplo, tudo começa com o pedido do cliente, então nosso producer é a API que recebe esses pedidos. Ao receber um pedido, o producer envia uma mensagem para nossa Exchange com todos os dados necessários para os outros serviços. Conforme recebe mais pedidos, a API continua adicionando mensagens na Exchange.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exchange:
&lt;/h2&gt;

&lt;p&gt;É como uma fila particular de mensagens do producer, responsável por direcionar as mensagens para o destino correto. O producer adiciona mensagens com os dados de cada pedido nessa fila. A Exchange, seguindo o esquema FIFO (First In, First Out), encaminha essas mensagens para determinadas Queues — outras filas com propósito diferente. A Exchange pode ter diferentes tipos, o que altera sua forma de distribuir as mensagens.&lt;/p&gt;

&lt;h2&gt;
  
  
  Queue:
&lt;/h2&gt;

&lt;p&gt;Assim como a Exchange, a Queue recebe mensagens — especificamente aquelas que a Exchange direcionou, contendo os dados dos pedidos. Seu propósito é armazenar essas mensagens para que os Consumers conectados possam obtê-las.&lt;/p&gt;

&lt;h2&gt;
  
  
  Consumer:
&lt;/h2&gt;

&lt;p&gt;O consumer obtém as mensagens da Queue seguindo o FIFO, acessa os dados do pedido e os processa. Em nosso e-commerce, exemplos de consumers são: o serviço que processa pagamentos conforme o valor do pedido, o que atualiza o estoque baseado na quantidade, e o que notifica o cliente. Esses serviços processam os dados sem prender o usuário em telas de carregamento, permitindo que ele continue fazendo outros pedidos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Um detalhe importante:&lt;/strong&gt; um Consumer também pode atuar como Producer e vice-versa. Por exemplo, o serviço de pagamento pode enviar mensagens para outros sistemas informando se o pagamento foi bem-sucedido. Os outros serviços podem então cancelar ou desfazer ações anteriores, e a API de pedidos pode retornar uma mensagem sobre a falha no pagamento.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo do esquema de mensagens:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsj9q5zdaekoclwpnqyh1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsj9q5zdaekoclwpnqyh1.png" alt="Exemplo do esquema de mensagens" width="800" height="547"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>rabbitmq</category>
      <category>learning</category>
      <category>performance</category>
    </item>
    <item>
      <title>Vazou a senha na linha de comando?</title>
      <dc:creator>Natanael Alves</dc:creator>
      <pubDate>Wed, 16 Oct 2024 16:09:01 +0000</pubDate>
      <link>https://dev.to/eunael/vazei-a-senha-na-linha-de-comando-2k6m</link>
      <guid>https://dev.to/eunael/vazei-a-senha-na-linha-de-comando-2k6m</guid>
      <description>&lt;p&gt;&lt;strong&gt;Relato&lt;/strong&gt;&lt;br&gt;
Estava eu acessando o terminal do servidor de produção e - sem querer querendo - executei um comando junto com uma senha de acesso que não deveria estar ali quando executasse esse comando. Agora, a senha estava exposta no histórico de comando do terminal. Felizmente encontrei uma forma de resolver isso e vou compartilhar para caso um dia, quem sabe, você precisar por algum motivo - mas ninguém precisar sabe que um dia você precisou fazer isso, certo?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Como fazer&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Primeiro, você executa o comando &lt;code&gt;history&lt;/code&gt; para saber em qual linha o comando a ser apagado está. Digamos que o comando está na linha &lt;code&gt;1234&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;Agora, só precisamos usar a flag &lt;code&gt;-d&lt;/code&gt; do comando history para apagar uma linha específica do histórico, assim:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;history -d 1234
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Para garanti que a linha foi apagada do histórico, usamos a flag -w para atualizar o histórico, assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;history -w
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se precisar de uma solução mais drástica para deletar um intervalo de linhas, você pode utilizar um &lt;code&gt;for loop&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for i in {[fim]..[início]}; do history -d $i; done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se precisa de algo ainda mais bruto, você pode apagar todo o histórico do terminal com a flag &lt;code&gt;-c&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;history -c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se quiser uma segurança a mais, no aquivo de configurações do terminal, você pode informar que comandos com certas palavras-chaves não vão ser registrado no histórico de comando. No meu caso, o arquivo de configs é o &lt;code&gt;.bashrc&lt;/code&gt; e nele eu disse que qualquer comando que tenha o termo "senha" ou "pass..." devem ser ignorados do histórico. Para isso, precisa apenas adicionar o seguinte trecho no arquivo de configuração:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export HISTIGNORE="*senha*:pass*:*history*-d*"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O valor atribuído à &lt;code&gt;HISTIGNORE&lt;/code&gt; é uma expressão regular e você pode adicionar várias separando-as por ":" .&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusão&lt;/strong&gt;&lt;br&gt;
Espero que isso nunca aconteça com você, mas, se um dia acontecer, está aí a solução e ninguém além de você vai saber disso hehehe. &lt;strong&gt;Mas tome cuidado pra não precisa usar essa artimanha de novo, blz?&lt;/strong&gt;. Espero que tenham gostado dessa e até a próxima.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Execute processos no linux sem interrupções com o nohup</title>
      <dc:creator>Natanael Alves</dc:creator>
      <pubDate>Tue, 24 Sep 2024 12:11:01 +0000</pubDate>
      <link>https://dev.to/eunael/execute-processos-no-linux-sem-interrupcoes-com-o-nohup-1eoj</link>
      <guid>https://dev.to/eunael/execute-processos-no-linux-sem-interrupcoes-com-o-nohup-1eoj</guid>
      <description>&lt;p&gt;&lt;strong&gt;Relato&lt;/strong&gt;&lt;br&gt;
Certo dia, já próximo ao fim do expediente, chegou uma demanda de um cliente solicitando o backup de 4 anos de dados dele registrados em um dos sistemas da empresa. Inicialmente, pensei em gerar um dump dos dados das tabelas e estava funcionando bem, exceto, pelo fato de que estava demorando muito pra terminar o processo e eu precisava ir embora, mas no outro dia esse backup devia ser entregue sem falta. E fui para resolver isso que encontrei o comando &lt;code&gt;nohup&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O que é o &lt;code&gt;nohup&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
É um comando no Linux que permite que você execute processos sem encerrá-los quando você fecha o terminal ou faz logout - o que era meu caso, pois estava acessando o servidor via SSH.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sintaxe&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nohup [seu comando] &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O nohup joga o comando para segundo plano e o &lt;code&gt;&amp;amp;&lt;/code&gt; joga a execução do nohup para segundo plano para liberar seu terminal. O output e os erros do seu comando, por padrão, vão ser escritos num arquivo chamado &lt;code&gt;nohup.out&lt;/code&gt; no diretório atual; porém, você pode especificar arquivos diferentes - veremos em frente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caso de uso&lt;/strong&gt;&lt;br&gt;
No meu caso, era um projeto Laravel e que criei um comando artisan para gerar o backup do cliente. Então, acessei o servidor via SSH, executei meu comando artisan com o nohup e fechei a sessão. Ficou assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nohup php artisan generateClientBackup &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output do comando&lt;/strong&gt;&lt;br&gt;
Meu comando mostrava no terminal quando terminava o dump de uma tabela, mas, como estava em segundo plano, eu perdia esse feedback. Pra resolver isso, eu redirecionei esses outputs do comando para um arquivo específico e o comando ficou o seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nohup php artisan generateClientBackup &amp;gt; output.log 2&amp;gt;$1 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Obs.:&lt;/strong&gt; em alguns caso, o comando podia dar erro e eu precisava desse feedback também. Então, mandei que os erros fossem para &lt;code&gt;output.log&lt;/code&gt; usando &lt;code&gt;2&amp;gt;$1&lt;/code&gt;, onde "2" representa a saída de erro e "$1" representa o arquivo output.log - mas pode-se especificar um nome para o arquivo de erro trocando $1 pelo nome do arquivo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cancelar processo em segundo plano&lt;/strong&gt;&lt;br&gt;
Se por algum motivo você precisar cancelar o processo depois de ter executado, pode usar o comando &lt;code&gt;kill&lt;/code&gt; informando o PID (Process ID) do processo:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Obtém o ID do processo:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ps aux | grep [seu comando]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Depois de encontrar o PID, use o comando:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kill [PID]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Bônus: seu comando espera um prompt?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo "valor_que_voce_quer_informar" | nohup php artisan blablabla &amp;gt; output.log 2&amp;gt;&amp;amp;1 &amp;amp;

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

&lt;/div&gt;



&lt;p&gt;O valor escrito pelo comando &lt;code&gt;echo&lt;/code&gt; serve como valor padrão para o prompt solicitado pelo seu comando.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusão&lt;/strong&gt;&lt;br&gt;
Com isso, você pode executar processos demorados sem precisar se preocupar em deixar seu terminal aberto o tempo todo. Mas ainda assim tem que ficar de olho se seu comando não retornou algum erro. Espero que tenham gostado dessa e até a próxima.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>devops</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Enums e lang no Laravel</title>
      <dc:creator>Natanael Alves</dc:creator>
      <pubDate>Tue, 17 Sep 2024 08:08:25 +0000</pubDate>
      <link>https://dev.to/eunael/enums-e-lang-no-laravel-43am</link>
      <guid>https://dev.to/eunael/enums-e-lang-no-laravel-43am</guid>
      <description>&lt;p&gt;&lt;strong&gt;Relato&lt;/strong&gt;&lt;br&gt;
Num projeto que trabalhei, havia um campo de select que tinha valores definidos e que não iriam ter alteração. Então, para listar os itens desse select, resolvi criar uma classe de enumeração e daí descrever esse valores. Porém, o projeto precisava dar suporte às linguagens inglês e espanhol, e o texto das opções do select precisavam de adaptar a isso sem perder a referência do respectivo item do enum. Ou seja, se eu selecionasse o item "cavalo", eu precisava que o sistema soubesse que esse item ainda é "cavalo" mesmo ele aparecendo como "horse" ou "caballo". Foi pra manter a integridades dos dados que criei a seguinte estrutura integrando o enum e o lang no projeto.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O que são os Enums&lt;/strong&gt;&lt;br&gt;
Uma breve introdução. A partir da versão 8.1 do PHP, foi introduzida uma classe especial para enumerar valores. Na prática, quer dizer que podemos criar uma classe que os valores das suas propriedades serão constantes. Um exemplo são status, pois se deixar livre provavelmente ao longo do código vai ter um status "ativo", outro "Ativo", outro "Active" slá. Mas seu amarra o status a um enum e usar o enum invés de digitar a string, terei a certeza que em qualquer lugar do código o valor vai ser sempre aquele que está no enum.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enum Status
{
    case ATIVO = "ativo";
    case INATIVO = "inativo";
    case PENDENTE = "pendente";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Enums e o lang&lt;/strong&gt;&lt;br&gt;
Como o enum é uma classe, eu posso criar métodos para a minha classe normalmente. Então, criei o método &lt;code&gt;display()&lt;/code&gt; que será o responsável por tratar a visualização do meu valor do enum adaptando-o para o idioma que o usuário está usando, porém, sem alterar o valor original no meu item do enum. Ou seja, para o usuário, o status aparece "Pendiente", ou "Pending", ou "Pendente"; mas no banco está salvo somente como "pendente" - que é o valor original e por ele eu consigo pegar o meu item do enum, e desse item usar o método display que mostrar ele traduzido para o usuário.&lt;br&gt;
Mas antes de mostrar o exemplo, uma introdução ao lang do Laravel. O lang é uma pasta na raiz do projeto para armazenar traduções que o seu projeto vai dar suporte. Cada idioma tem uma pasta, e nessa pasta arquivos para contextos de traduções. Nesses arquivos tem um array, onde a chave é uma representação da palavra e o valor é a tradução para o respectivo idioma.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Configurando o método display&lt;/strong&gt;&lt;br&gt;
Na pasta lang, vou criar um arquivo &lt;code&gt;status.php&lt;/code&gt; para cada pasta de idioma com o seguinte array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php
[
    Status::ATIVO-&amp;gt;value =&amp;gt; "Ativo",
    Status::INATIVO-&amp;gt;value =&amp;gt; "Inativo",
    Status::PENDENTE-&amp;gt;value =&amp;gt; "Pendente",
];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Corrijo os valores do array para a respectiva traduções do respectivo idioma.&lt;br&gt;
E meu método display vai buscar a tradução do item do enum nesses arquivos &lt;code&gt;status.php&lt;/code&gt; e retornar esse valor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function display(): string
{
    return trans('status.'.$this-&amp;gt;value);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exemplo de uso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// EN
echo Status::ATIVO-&amp;gt;display(); // Active

// PT_BR
echo Status::INATIVO-&amp;gt;display(); // Inativo

// ES
echo Status::PENDENTE-&amp;gt;display(); // Pediente
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Conclusão&lt;/strong&gt;&lt;br&gt;
Com isso, eu garanto que meu valor do enum continue constante no meu código, mas ele se adapta ao idioma do usuário usando o método display sem perder a integridade dos dados. Além também de ficar flexível caso eu adicione um novo idioma ao sistema. Espero que tenham gostado dessa e até a próxima.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>php</category>
      <category>laravel</category>
    </item>
  </channel>
</rss>
