<?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: Matheus Silva</title>
    <description>The latest articles on DEV Community by Matheus Silva (@matheusdsilva01).</description>
    <link>https://dev.to/matheusdsilva01</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F888049%2F3a8d486c-5764-4515-a75b-956dfa223f4e.webp</url>
      <title>DEV Community: Matheus Silva</title>
      <link>https://dev.to/matheusdsilva01</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/matheusdsilva01"/>
    <language>en</language>
    <item>
      <title>5 lições de segurança que aprendi estudando um host temporário de arquivos</title>
      <dc:creator>Matheus Silva</dc:creator>
      <pubDate>Thu, 15 Oct 2026 18:18:49 +0000</pubDate>
      <link>https://dev.to/matheusdsilva01/5-licoes-de-seguranca-que-aprendi-estudando-um-host-temporario-de-arquivos-5fab</link>
      <guid>https://dev.to/matheusdsilva01/5-licoes-de-seguranca-que-aprendi-estudando-um-host-temporario-de-arquivos-5fab</guid>
      <description>&lt;p&gt;Estudei como funciona um projeto open-source de host temporário de arquivos, o Waifuvault, e criei um utilizando Laravel. Neste artigo, vou compartilhar 5 lições de segurança que são essenciais nesse tipo de aplicação e um pouco da experiência de criar esse projeto utilizando Laravel.&lt;/p&gt;

&lt;h3&gt;
  
  
  Não confie no que é enviado pelo usuário
&lt;/h3&gt;

&lt;p&gt;Provavelmente você já deve ter ouvido essa frase e nesse tipo de aplicação, é importante fazer a validação dos dados enviados pelo usuário, como nome do arquivo, headers como &lt;code&gt;Content-Type&lt;/code&gt; e &lt;code&gt;Content-Length&lt;/code&gt; que são variáveis importantes nesse contexto.&lt;/p&gt;

&lt;p&gt;Dado um cenário em que é enviado um arquivo de 10mb, o servidor precisa verificar o tamanho real recebido para garantir que não ultrapasse o limite permitido pela aplicação.&lt;/p&gt;

&lt;p&gt;Uma forma de se prevenir isso é durante o recebimento de arquivos por streaming verificar os bytes recebidos conforme for armazenando. Se o limite for atingido, ocorrer uma falha ou divergência, o upload deve ser rejeitado e o arquivo parcial que estava sendo salvo deve ser removido, evitando registros órfãos no sistema.&lt;/p&gt;

&lt;p&gt;Também é uma boa prática alterar o nome do arquivo para algo gerado pela aplicação, como um UUID. Isso reduz riscos de  sobrescrita de arquivos e uso de nomes maliciosos para sua aplicação.&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD
    A[Usuário envia o arquivo] --&amp;gt; B[Servidor grava os bytes no storage]
    B --&amp;gt; C{Tamanho gravado é&amp;lt;br/&amp;gt;igual ao informado?}
    C -- Sim --&amp;gt; D[Upload aceito]
    C -- Não --&amp;gt; E[Upload rejeitado]
    E --&amp;gt; F[Apaga o arquivo parcial&amp;lt;br/&amp;gt;do storage]&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;
  
  
  Validar o conteúdo real do arquivo, não o que ele diz ser
&lt;/h3&gt;

&lt;p&gt;Complementando um pouco o tópico anterior, essa é uma parte interessante, por exemplo, o que pode acontecer é o usuário enviar um arquivo informando uma extensão e &lt;code&gt;Content-Type&lt;/code&gt; de .pdf mas o MIME type do conteúdo indica que se trata de um arquivo .png, mais uma divergência das informações e uma possível vulnerabilidade para o sistema.&lt;br&gt;
Para identificar o real conteúdo de um arquivo, se é uma foto .png, .jpeg, vídeo .mp4, áudio .mp3, podemos verificar os primeiros bytes do conteúdo. Eles indicam o verdadeiro tipo de arquivo quase como uma assinatura mesmo, então mesmo que você renomeie o arquivo e mude a extensão o conteúdo vai ser o mesmo.&lt;br&gt;
Um teste rápido: pegue um arquivo .png qualquer real e use a ferramenta &lt;code&gt;xxd&lt;/code&gt; no Linux. Note que os primeiros bytes retornados são &lt;code&gt;8950 4e47&lt;/code&gt;, renomeie esse arquivo para "sexta.pdf" e verifique novamente, os bytes serão os mesmos, é uma curiosidade bem legal.&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD
    A["Usuário envia shell.png"] --&amp;gt; B[Servidor lê os primeiros bytes&amp;lt;br/&amp;gt;do arquivo]
    B --&amp;gt; C[Detecta o tipo real&amp;lt;br/&amp;gt;pela assinatura]
    C --&amp;gt; D{Tipo real bate com&amp;lt;br/&amp;gt;o informado?}
    D -- Sim --&amp;gt; E[Upload segue o fluxo]
    D -- Não --&amp;gt; F[Upload rejeitado]&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;Mostrando um pouquinho de código, como o Laravel é um Framework bem completo, é até simples fazer essa validação dentro um &lt;code&gt;FormRequest&lt;/code&gt;, segue o exemplo abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Validation\Validator&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;withValidator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Validator&lt;/span&gt; &lt;span class="nv"&gt;$validator&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$validator&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;after&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Validator&lt;/span&gt; &lt;span class="nv"&gt;$validator&lt;/span&gt;&lt;span class="p"&gt;)&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="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'file'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isValid&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;}&lt;/span&gt;

        &lt;span class="nv"&gt;$clientMime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getClientMimeType&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$contentMime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getMimeType&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$clientMime&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nv"&gt;$contentMime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$validator&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;errors&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;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="s1"&gt;'file'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'O MIME type informado não corresponde ao conteúdo do arquivo.'&lt;/span&gt;
            &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Convergência entre dois sistemas(Storage e Banco)
&lt;/h3&gt;

&lt;p&gt;No primeiro tópico, falei sobre evitar registros órfãos no sistema algo que pode acontecer caso o arquivo seja salvo no storage mas por algum motivo o insert no banco falhar, ou também o contrário disso.&lt;br&gt;
Para isso é importante manter o Storage e o Banco de dados em sincronia quanto ao estado de um registro.&lt;br&gt;
Acredito que a ordem de salvar primeiro o arquivo no storage e, depois, registrar os metadados no banco de dados seja a mais apropriada, para caso o insert falhe faça a limpeza do arquivo no Storage.&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD
    A[Salva o arquivo no storage] --&amp;gt; B[Insere o registro no banco]
    B --&amp;gt; C{Insert funcionou?}
    C -- Sim --&amp;gt; D[Arquivo e registro em sincronia]
    C -- Não --&amp;gt; E[Apaga o arquivo do storage]
    E --&amp;gt; F[Nenhum órfão fica no sistema]&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;
  
  
  Storage privado exige entrega mediada
&lt;/h3&gt;

&lt;p&gt;Quando você vai entregar um arquivo ao usuário por um link, isso não é simplesmente entregar a URL do storage para acessar o arquivo diretamente. Isso impossibilitaria a aplicação de regras de acesso, senha e expiração, além de poder expor arquivos.&lt;br&gt;
Por isso, o acesso por link deve passar pela a aplicação, para sejam aplicadas essas validações de regras de negócio antes de disponibilizar o arquivo.&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart LR
    A[Usuário acessa o link] --&amp;gt; B[Aplicação]
    B --&amp;gt; C{Regras válidas?&amp;lt;br/&amp;gt;expiração, senha, downloads}
    C -- Não --&amp;gt; D[Responde com erro&amp;lt;br/&amp;gt;ex.: 404]
    C -- Sim --&amp;gt; E[(Storage privado)]
    E --&amp;gt; F[Aplicação devolve&amp;lt;br/&amp;gt;o arquivo ao usuário]&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;
  
  
  Expiração não é o mesmo que limpeza
&lt;/h3&gt;

&lt;p&gt;Expiração é um estado do arquivo no sistema, o arquivo não é mais disponibilizado pelo servidor, então a tentativa de acesso por link é inválida.&lt;br&gt;
Limpeza é a ação de apagar o arquivo do armazenamento e seus metadados do banco de dados.&lt;br&gt;
A limpeza não precisa ser feita no momento em que o arquivo expira, ela pode ser feita por um cron job periódico, como a entrega é mediada pela aplicação a tentativa de acesso por link retornaria um erro 404.&lt;br&gt;
Logo, um arquivo pode estar expirado, mas ainda existir no armazenamento até que uma ação de limpeza o exclua.&lt;br&gt;
Para a limpeza no Laravel, utilizei um Schedule simples diário e a trait &lt;code&gt;Prunable&lt;/code&gt; que facilita a exclusão de registros.&lt;/p&gt;

&lt;p&gt;Vou deixar trechos de código da implementação e seguem os links da documentação para ver mais sobre: &lt;a href="https://laravel.com/framework/docs/13.x/eloquent#pruning-models" rel="noopener noreferrer"&gt;pruning-models&lt;/a&gt; e &lt;a href="https://laravel.com/framework/docs/13.x/scheduling" rel="noopener noreferrer"&gt;schedule&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/**
 * Define a query que seleciona arquivos expirados para remoção.
 *
 * @return Builder&amp;lt;static&amp;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;prunable&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;Builder&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="nf"&gt;newQuery&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;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'expires_at'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;='&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cd"&gt;/**
 * Exclui o arquivo armazenado antes de remover seus dados do banco.
 */&lt;/span&gt;
&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;pruning&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nc"&gt;Storage&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;disk&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="n"&gt;disk&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;delete&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="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RuntimeException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"The expired file [&lt;/span&gt;&lt;span class="si"&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;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;] could not be deleted."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// E o schedule diário para a limpeza&lt;/span&gt;
&lt;span class="nc"&gt;Schedule&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'model:prune'&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;daily&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Considerações finais
&lt;/h3&gt;

&lt;p&gt;Foi muito legal estudar um sistema open-source que uso no dia a dia, além de criar um sistema com essa finalidade e aprendendo mais funcionalidades do Laravel, espero que esse artigo tenha lhe ajudado de alguma forma.&lt;/p&gt;

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

&lt;p&gt;Waifuvault, o projeto que estudei: &lt;a href="https://waifuvault.moe/" rel="noopener noreferrer"&gt;https://waifuvault.moe/&lt;/a&gt;&lt;br&gt;
Resumo dos meus estudos: &lt;a href="https://github.com/matheusdsilva01/learning/tree/main/about-waifuvault" rel="noopener noreferrer"&gt;https://github.com/matheusdsilva01/learning/tree/main/about-waifuvault&lt;/a&gt;&lt;br&gt;
Guia de segurança da OWASP sobre envio de arquivos:&lt;br&gt;
&lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html" rel="noopener noreferrer"&gt;https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html&lt;/a&gt;&lt;br&gt;
Projeto que desenvolvi: &lt;a href="https://github.com/matheusdsilva01/temp67" rel="noopener noreferrer"&gt;https://github.com/matheusdsilva01/temp67&lt;/a&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>learning</category>
      <category>php</category>
      <category>laravel</category>
    </item>
    <item>
      <title>Feature-based: por que sua pasta components virou uma bagunça?</title>
      <dc:creator>Matheus Silva</dc:creator>
      <pubDate>Fri, 21 Aug 2026 19:37:54 +0000</pubDate>
      <link>https://dev.to/matheusdsilva01/feature-based-por-que-sua-pasta-components-virou-uma-bagunca-51lc</link>
      <guid>https://dev.to/matheusdsilva01/feature-based-por-que-sua-pasta-components-virou-uma-bagunca-51lc</guid>
      <description>&lt;p&gt;Acho que todo dev já passou pelo momento de se deparar com um projeto e se perder no meio de tantos arquivos. Isso pode ser resultado de N fatores, e um deles pode ser a forma como o projeto está organizado.&lt;/p&gt;

&lt;p&gt;Falando especificamente de frontend, quando criamos um projeto do zero em qualquer framework, ele vai lhe entregar uma estrutura padrão, chamada de &lt;code&gt;Type-based&lt;/code&gt; em que você consegue desenvolver coisas simples, nada muito complexo ou escalável. Você vai conseguir seguir essa estrutura inicial e entregar as features necessárias, e é isso.&lt;/p&gt;

&lt;p&gt;Até certo ponto, beleza: tudo funciona, você consegue se localizar entre as pastas e arquivos. Aí você vai integrando mais endpoints da API, adicionando features, novos fluxos, e então as coisas ficam entrelaçadas, distantes e muito desorganizadas. Implementar uma feature nova já não é tão simples, e se localizar é pior ainda.&lt;/p&gt;

&lt;h3&gt;
  
  
  Por que essa dor?
&lt;/h3&gt;

&lt;p&gt;Isso foi uma experiência própria que vivi em projetos que desenvolvi, e que despertou minha curiosidade sobre como estruturar melhor meus projetos. Aí encontrei algumas possibilidades de arquiteturas, como DDD, Clean Architecture, MVC e Micro-frontend. Mas muitas delas eram voltadas para projetos backend, eu não via com bons olhos trazer isso para o frontend moderno e também me pareciam soluções muito complexas para algo simples.&lt;/p&gt;

&lt;h3&gt;
  
  
  Uma solução... Simples?
&lt;/h3&gt;

&lt;p&gt;Foi aí que encontrei uma solução chamada &lt;code&gt;Feature-based&lt;/code&gt;. É uma abordagem que parece simples, em resumo: você pega seu projeto e quebra em partes. Que partes? Bom, aí pode ser por entidade, domínio, etc. Essa quebra traz algo interessante, que é a modularidade: seu sistema agora está mais desacoplado, cada parte passa a ser autogerenciável, tem sua própria responsabilidade e seu propósito bem definido.&lt;/p&gt;

&lt;p&gt;Dando um exemplo visual antes de seguirmos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├── features/
│   ├── movies/
│   │   ├── components/
│   │   ├── hooks/
│   │   ├── api/
│   │   └── types/
│   ├── comments/
│   │   ├── components/
│   │   ├── hooks/
│   │   ├── api/
│   │   └── types/
│   └── auth/
│       ├── components/
│       ├── hooks/
│       ├── api/
│       └── types/
├── shared/
│   ├── components/
│   ├── hooks/
│   └── utils/
└── app/
    ├── routes/
    └── layout/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Prós e contras
&lt;/h3&gt;

&lt;p&gt;Os prós? &lt;strong&gt;Organização&lt;/strong&gt;: Você consegue identificar com facilidade onde trabalhar. &lt;strong&gt;Testabilidade&lt;/strong&gt;: Seus fluxos de testes de e2e, integração e unitários ficam melhor localizados. E &lt;strong&gt;escalabilidade&lt;/strong&gt;: Surgiu um fluxo novo? Para qual feature? Altere o código na pasta da feature que vai receber a implementação. Surgiu uma feature, entidade nova? Literalmente crie uma pasta nova em features... ou não. Acredito que aqui é um bom momento para falar dos contras.&lt;/p&gt;

&lt;p&gt;Dando um contexto para facilitar o entendimento: imagine um cenário em que vamos adicionar os nomes das empresas produtoras na página de detalhes de um filme. Primeiro pensamento: nova entidade &lt;code&gt;companies&lt;/code&gt;, logo vamos criar uma pasta nova de &lt;code&gt;companies&lt;/code&gt; em features. O backend vai ter um endpoint &lt;code&gt;/companies?movie_id=?&lt;/code&gt;, jogamos isso dentro de &lt;code&gt;companies&lt;/code&gt; e &lt;code&gt;movies&lt;/code&gt; vai importar o que for necessário dali. Resolvido, isso está errado? Não, é um excelente caminho e segue os requisitos para ser uma feature nova no projeto. Mas, nesse momento, é somente uma chamada para a API que retorna uma lista simples. Outra possibilidade, que também não estaria incorreta, é um simples &lt;code&gt;getMovieCompanies&lt;/code&gt; dentro de &lt;code&gt;features/movies&lt;/code&gt; — nesse momento é aceitável. Mas, caso &lt;code&gt;companies&lt;/code&gt; ganhe mais fluxos e telas no projeto, aí o próximo passo é mover essa lógica para dentro de &lt;code&gt;features/companies&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;"Como isso se encaixa em um contra?" Aqui entra o ponto de maturidade para tomar esse tipo de decisão de implementação e levar em conta os trade-offs — nesse caso, o trabalho de criar uma nova feature versus a simplicidade do momento, em troca de uma possível refatoração no futuro. Obviamente esse exemplo é bem simples, usado só para ilustrar um cenário que poderia acontecer em um projeto real.&lt;/p&gt;

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

&lt;p&gt;Com a IA muito presente no dia a dia de desenvolvimento, acredito que ter essa preocupação com a estrutura do projeto é importante. Sem uma estrutura bem definida, é fácil um agente duplicar lógica sem você perceber e só acabar aceitando o que foi gerado porque, aparentemente, está tudo funcionando como esperado&lt;/p&gt;

&lt;p&gt;É isso, tem mais pontos que podem ser abordados como circular dependency, deep import, arquivos compartilhados mas isso já é um bom introdutório para pensar sobre como organizar seus projetos.&lt;br&gt;
Se quiser se aprofundar mais sobre o assunto deixo aqui um pouco do que foi meu estudo sobre esse tópico contém alguns resumos e lições sobre testes, definição de features, discussões mais técnicas sobre implementação e você pode encontrar alguns exemplos de código sobre &lt;code&gt;Feature-based&lt;/code&gt;: &lt;a href="https://github.com/matheusdsilva01/learning/tree/main/learning-feature-based" rel="noopener noreferrer"&gt;https://github.com/matheusdsilva01/learning/tree/main/learning-feature-based&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Espero que isso tenha lhe incentivado a estruturar melhor seus projetos e tmj&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/alan2207/bulletproof-react/" rel="noopener noreferrer"&gt;https://github.com/alan2207/bulletproof-react/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>frontend</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Porque o PostgreSQL é tão queridinho?</title>
      <dc:creator>Matheus Silva</dc:creator>
      <pubDate>Tue, 23 Jun 2026 19:30:46 +0000</pubDate>
      <link>https://dev.to/matheusdsilva01/porque-o-postgresql-e-tao-queridinho-3eh0</link>
      <guid>https://dev.to/matheusdsilva01/porque-o-postgresql-e-tao-queridinho-3eh0</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;PostgreSQL é um dos bancos de dados relacionais mais populares no mundo por alguns motivos e tudo isso começou como um simples projeto de faculdade, hoje sendo a principal ferramenta adotada por grandes projetos e empresas no mundo.&lt;br&gt;
E neste artigo vou dar um pouco de contexto de como ele alcançou esse posto.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Table of contents&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Historinha&lt;/li&gt;
&lt;li&gt;Open source&lt;/li&gt;
&lt;li&gt;Extensões&lt;/li&gt;
&lt;li&gt;Confiabilidade&lt;/li&gt;
&lt;li&gt;Comparativo&lt;/li&gt;
&lt;li&gt;Conclusão&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Historinha
&lt;/h2&gt;

&lt;p&gt;Contando um pouco de historia, o PostgreSQL nasceu dentro da universidade de Berkeley nos Estados Unidos ja com o objetivo em extensibilidade e suporte a tipos de dados complexos, como pesquisa científica inicialmente chamado de apenas Postgres. E foi crescendo, mais tarde tendo suporte para SQL sendo nomeado como PostgreSQL e lançado para web ganhando performance e mais manutenção.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open source
&lt;/h2&gt;

&lt;p&gt;O PostgreSQL não tem um único dono, hoje é mantido pela PostgreSQL Global Development Group um agromerado de empresas e desenvolvedores que contribuem para o projeto sem o poder de tomada de decisões de forma unilateral sobre o projeto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extensões
&lt;/h2&gt;

&lt;p&gt;Graças a compatibilidade com extensões é possivel usar o PostgreSQL para vários propósitos algumas extensões famosas são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;PostGis&lt;/em&gt;: A possibilidade de processamento de dados geográficos e espaciais.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;pgvector&lt;/em&gt;: Para uso de Inteligência Artificial o pgvector possibilita a busca vetorial em embeddings.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Confiabilidade
&lt;/h2&gt;

&lt;p&gt;A partir de 2001 se tornou ACID(Atomicidade, Consistência, Isolamento e Durabilidade) garantindo segurança, robustez e confiabilidade para os usuários. Também possui mecanismo de MVCC(Multi Version Concurrency Control) para não bloquear ações de leitura e escrita otimizando paralelismo e garantindo performance em ambiente com grande tráfego.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparativo
&lt;/h2&gt;

&lt;p&gt;Mesmo levando em consideração outras opções conhecidas do mercado como MySQL, Oracle e até mesmo não relacional como MongoDB, PostgreSQL ainda tem uma grande aceitação para uma aplicação que seja pequena ou grande porte.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Critério&lt;/th&gt;
&lt;th&gt;PostgreSQL&lt;/th&gt;
&lt;th&gt;MySQL / MariaDB&lt;/th&gt;
&lt;th&gt;MongoDB&lt;/th&gt;
&lt;th&gt;Oracle DB&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Paradigma&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Relacional (Objeto-Relacional)&lt;/td&gt;
&lt;td&gt;Relacional&lt;/td&gt;
&lt;td&gt;Documento (NoSQL)&lt;/td&gt;
&lt;td&gt;Relacional&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Licença&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Open Source (Permissiva)&lt;/td&gt;
&lt;td&gt;Open Source (GPL) / Comercial&lt;/td&gt;
&lt;td&gt;Source-available (SSPL)&lt;/td&gt;
&lt;td&gt;Proprietária (Muito cara)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Extensibilidade&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Excelente (UDFs, Extensions, FDW)&lt;/td&gt;
&lt;td&gt;Limitada&lt;/td&gt;
&lt;td&gt;Limitada&lt;/td&gt;
&lt;td&gt;Excelente, mas proprietária&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Suporte a JSON&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Excelente (&lt;code&gt;jsonb&lt;/code&gt; indexado)&lt;/td&gt;
&lt;td&gt;Bom&lt;/td&gt;
&lt;td&gt;Nativo&lt;/td&gt;
&lt;td&gt;Bom, mas complexo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Principais Usos&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sistemas financeiros, IA, GIS, aplicações robustas de qualquer porte&lt;/td&gt;
&lt;td&gt;Aplicações web tradicionais, WordPress, e-commerces simples&lt;/td&gt;
&lt;td&gt;Protótipos rápidos, catálogos flexíveis, dados semi-estruturados&lt;/td&gt;
&lt;td&gt;Grandes corporações legadas, ERPs de altíssima escala&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;Se você precisa de segurança, flexibilidade e robustez, o PostgreSQL faz por merecer esse posto de queridinho.&lt;/p&gt;

</description>
      <category>database</category>
      <category>braziliandevs</category>
      <category>postgressql</category>
      <category>software</category>
    </item>
    <item>
      <title>O básico para gerenciar e se proteger de vulnerabilidades em dependências no seu projeto Node.</title>
      <dc:creator>Matheus Silva</dc:creator>
      <pubDate>Mon, 20 Apr 2026 19:20:05 +0000</pubDate>
      <link>https://dev.to/matheusdsilva01/o-basico-para-gerenciar-e-se-proteger-de-vulnerabilidades-em-dependencias-no-seu-projeto-node-3gnk</link>
      <guid>https://dev.to/matheusdsilva01/o-basico-para-gerenciar-e-se-proteger-de-vulnerabilidades-em-dependencias-no-seu-projeto-node-3gnk</guid>
      <description>&lt;p&gt;Verificar e eliminar vulnerabilidades em dependências pode ser mais simples do que você imagina e lhe garanto que isso pode salvar seu tempo e te livrar de algumas dores de cabeça no futuro.&lt;/p&gt;

&lt;p&gt;Antes de tudo, é importante saber gerenciar as dependências do seu projeto e entender como o seu gerenciador de pacote faz uma parte do trabalho para você, nesse artigo vou abordar os seguintes tópicos:&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Table of contents&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;SemVer&lt;/li&gt;
&lt;li&gt;Relação entre package.json e package-lock.json&lt;/li&gt;
&lt;li&gt;Lidando com vulnerabilidades&lt;/li&gt;
&lt;li&gt;Conclusão&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Antes de falar sobre as vulnerabilidades em si, acho importante uma explicação básica sobre o que significa a sigla SemVer (Semantic Version) e como funciona a relação do &lt;code&gt;package.json&lt;/code&gt;com o &lt;code&gt;package-lock.json&lt;/code&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  SemVer
&lt;/h2&gt;

&lt;p&gt;SemVer, ou Versionamento Semântico, é uma especificação para ajudar desenvolvedores a entender as mudanças e atualizações durante o versionamento de pacote.&lt;/p&gt;

&lt;p&gt;Uma versão de pacote é definida em 3 números &lt;code&gt;Major.Minor.Patch&lt;/code&gt; (ex: 2.3.14), bom o que significa cada número desse:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Major (2): Uma versão com atualizações que não tem compatibilidade com versões major anteriores. Então se você atualizar da 1.0 para 2.0 pode ser que isso cause algum problema quando você executar seu projeto, seja por alguma funcionalidade obsoleta ou alguma mudança na sua utilização, etc.&lt;/li&gt;
&lt;li&gt;Minor (2.3): Uma versão que adiciona recursos que tem compatibilidade com versões minor anteriores, ou seja, atualizações dentro da mesma versão major não devem quebrar seu sistema.&lt;/li&gt;
&lt;li&gt;Patch (2.3.14): Normalmente uma versão para lançar correções de bugs, vulnerabilidades e claro mantendo compatibilidade com versões de patch anteriores.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Aqui não tem muito segredo, então quando você ouvir algo do tipo “tal pacote já lançou uma versão de patch(x) pra corrigir aquela vulnerabilidade da V14.3” é uma versão 14.3.x (entenda x como qualquer número).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Intervalo de versões (^, ~)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Algo fora dessa especificação são os sinais de circunflexo &lt;code&gt;^&lt;/code&gt; e til &lt;code&gt;~&lt;/code&gt; , que você comumente verá em projetos, são usados para definir intervalo de versões e sinalizar para o npm como ele deve lidar com as atualizações da dependência.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;^&lt;/code&gt; circunflexo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Permite atualizações até versões minor mas não major, por exemplo: 2.3 pode atualizar para 2.4 mas por conta própria não vai fazer uma atualização de versão para major 3.x&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;~&lt;/code&gt; til&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Permite atualizações apenas de versões patch dentro da minor especificada, por exemplo: 2.3.14 pode atualizar para 2.3.20. E claro não vai atualizar para uma versão 2.4&lt;/p&gt;

&lt;p&gt;Também é possível não especificar um intervalo de versões, dessa forma a instalação é fixada em uma versão e só pode ser alterada manualmente com uso do &lt;code&gt;npm install&lt;/code&gt; por exemplo.&lt;/p&gt;

&lt;p&gt;Definir um intervalo de versões vai trazer mais segurança e praticidade quando precisar dependências mas caso precise de um controle mais rígido pode travar em uma versão sem problemas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Relação entre package.json e package-lock.json
&lt;/h2&gt;

&lt;p&gt;São arquivos que se completam. &lt;/p&gt;

&lt;p&gt;O &lt;code&gt;package.json&lt;/code&gt; salva as dependências do projeto, é onde você vai ter um overview geral e pode definir o intervalo de versões.&lt;/p&gt;

&lt;p&gt;O &lt;code&gt;package-lock.json&lt;/code&gt; é quem vai controlar a árvore de dependências e definir qual a versão exata que vai ser instalada, claro seguindo a referência definida no &lt;code&gt;package.json&lt;/code&gt;, garantindo que todas as instalações tenham as mesmas versões de dependências, por isso é muito importante você manter o &lt;code&gt;package-lock.json&lt;/code&gt; commitado/salvo no seu repositório além de deixar processo de instalação mais rápido vai dar consistência entre diferentes ambientes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lidando com vulnerabilidades
&lt;/h2&gt;

&lt;p&gt;O npm nos forcene basicamente duas funcionalidades para identificar e resolver vulnerabilidades em nossas dependências.&lt;/p&gt;

&lt;h3&gt;
  
  
  npm audit e npm audit fix
&lt;/h3&gt;

&lt;p&gt;Para verifica se as versões instaladas das dependências no projeto contém alguma vulnerabilidade conhecida, &lt;code&gt;npm audit&lt;/code&gt; eu diria que é o primeiro passo. Executar esse comando no seu terminar vai gerar algo como:&lt;br&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%2F0lo18ofkd9f4e2y3sbmc.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%2F0lo18ofkd9f4e2y3sbmc.png" alt="npm audit report" width="800" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nesse exemplo estou com a versão 16.1.6 do Next, aqui o relatório indica que nesse projeto só tenho vulnerabilidade nessa dependência e essa versão está dentro de um range de 6 vulnerabilidades conhecidas e como pelo menos uma delas tem gravidade de nível &lt;code&gt;high&lt;/code&gt; a gravidade geral é essa, mesmo se algumas delas tiverem nível menor, também retorna links com mais informações sobre elas. &lt;/p&gt;

&lt;p&gt;Para eliminar essas vulnerabilidades, como no meu &lt;code&gt;package.json&lt;/code&gt; defini o pacote do Next como &lt;code&gt;^16.1.6&lt;/code&gt; (olha o ^) e existe uma correção para essas vulnerabilidades dentro desse intervalo de versão definido, isso permite que apenas executando &lt;code&gt;npm audit fix&lt;/code&gt; ele atualize a dependência para uma versão sem vulnerabilidades.&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%2Flzb4y0cmsdjedh2iwbuj.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%2Flzb4y0cmsdjedh2iwbuj.png" alt="npm audit fix report" width="428" height="95"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aqui foi feita uma atualização para &lt;code&gt;16.2.4&lt;/code&gt; mas e se tivesse definido com &lt;code&gt;~&lt;/code&gt; ? Fica aí a lição de casa.&lt;/p&gt;

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

&lt;p&gt;Escrevi esse artigo com o propósito de fixação do conteúdo que estudei e deixo aqui alguns tópicos para se aprofundar sobre o assunto.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dependabot&lt;/li&gt;
&lt;li&gt;.npmrc (save-exact, audit-level)&lt;/li&gt;
&lt;li&gt;Snyk&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=kK4Meix58R4" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=kK4Meix58R4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://semver.org/lang/pt-BR/" rel="noopener noreferrer"&gt;https://semver.org/lang/pt-BR/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.npmjs.com/cli/v11/configuring-npm/package-lock-json" rel="noopener noreferrer"&gt;https://docs.npmjs.com/cli/v11/configuring-npm/package-lock-json&lt;/a&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>npm</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Controlando cache através do navegador</title>
      <dc:creator>Matheus Silva</dc:creator>
      <pubDate>Fri, 12 Dec 2025 21:22:10 +0000</pubDate>
      <link>https://dev.to/matheusdsilva01/controlando-cache-atraves-do-navegador-1h6j</link>
      <guid>https://dev.to/matheusdsilva01/controlando-cache-atraves-do-navegador-1h6j</guid>
      <description>&lt;p&gt;&lt;code&gt;Cache&lt;/code&gt; você já deve ter ouvido esse termo várias vezes e recentemente resolvi aprender como o navegador implementa esse mecanismo e então resolvi escrever esse post sobre o que aprendi.&lt;/p&gt;

&lt;p&gt;Contextualizando, &lt;code&gt;Cache&lt;/code&gt; é um mecanismo utilizado com a finalidade de trazer velocidade ao acesso um conteúdo que é frequentemente utilizado.&lt;/p&gt;

&lt;p&gt;Quando estamos implementando cache em nosso sistema é importante mantê-lo o mais próximo possível do cliente e para isso podemos usar o sistema de cache dos navegadores assim mantendo velocidade no acesso ao conteúdo e salvando recursos de nossos servidores.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tipos de cache
&lt;/h2&gt;

&lt;p&gt;Para gerenciar cache no navegador usamos o header &lt;code&gt;Cache-Control&lt;/code&gt; e podemos trabalhar com os seguintes valores para ele:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;default&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Por padrão o seguinte fluxo será seguido:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Se for encontrada em cache uma versão atualizada dos dados essa será retornada.&lt;/li&gt;
&lt;li&gt;Caso seja obsoleta será feita uma espécie de consulta ao servidor e verificar se os dados do cache sofreram alterações, se sofreram alteração os dados atualizados vão ser retornados e atualizados no cache, caso contrário o dado do cache será retornado.&lt;/li&gt;
&lt;li&gt;Se não for encontrado nada em cache será feita a requisição ao servidor e o cache vai ser atualizado com os dados retornados.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;no-store&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;O navegador vai ignorar o cache, efetuar a requisição para o servidor e não irá armazenar o retorno no cache.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;reload&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;O navegador vai ignorar o cache, efetuar a requisição para o servidor e vai atualizar o cache com o retorno da requisição.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;no-cache&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;O navegador verifica no cache se existe alguma versão atualizada dos dados ou obsoleta depois disso é verificado com o servidor se há uma nova versão dos dados, se houver será retornado a nova versão pelo servidor e o cache será atualizado, se não a versão do cache vai ser retornada.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;force-cache&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;O navegador verifica o cache, se encontrar uma versão atualizada ou obsoleta dos dados ela vai ser retornada se não encontrar nada no cache ele vai fazer a requisição normalmente no servidor retornando os dados e salvando no cache.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;max-age=&amp;lt;valor em segundos&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Pode ser usado em conjunto com os valores acima e define por quanto tempo aquele dado é definido como “atualizado”.&lt;/p&gt;

&lt;p&gt;Também e possível gerenciar o cache usando o header &lt;code&gt;Expires&lt;/code&gt; que pode ser definido com um tempo específico, exemplo: &lt;code&gt;Expires: Thu, 25 Dec 2025 18:18:18 GMT&lt;/code&gt; ou seja a partir do tempo especificado aquele dado passa a ser obsoleto.&lt;/p&gt;

&lt;p&gt;Esse foi o conteúdo que estudei espero que tenha agregado de alguma forma. 😊 &lt;/p&gt;

&lt;p&gt;Referências: &lt;br&gt;
&lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Guides/Caching" rel="noopener noreferrer"&gt;https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Guides/Caching&lt;/a&gt;&lt;br&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Request/cache" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/API/Request/cache&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>browser</category>
      <category>programming</category>
      <category>web</category>
    </item>
  </channel>
</rss>
