<?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: Nathalia Pavan</title>
    <description>The latest articles on DEV Community by Nathalia Pavan (@nathaliapavan).</description>
    <link>https://dev.to/nathaliapavan</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%2F484105%2Ff41b4a18-cf2e-4221-b372-d228b4e255df.jpeg</url>
      <title>DEV Community: Nathalia Pavan</title>
      <link>https://dev.to/nathaliapavan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nathaliapavan"/>
    <language>en</language>
    <item>
      <title>Live reload em Go com docker e compile daemon</title>
      <dc:creator>Nathalia Pavan</dc:creator>
      <pubDate>Thu, 25 Apr 2024 21:13:55 +0000</pubDate>
      <link>https://dev.to/nathaliapavan/live-reload-em-go-com-docker-e-compile-daemon-57lj</link>
      <guid>https://dev.to/nathaliapavan/live-reload-em-go-com-docker-e-compile-daemon-57lj</guid>
      <description>&lt;p&gt;Desenvolver aplicações em Go é bastante produtivo, principalmente quando conseguimos combinar ferramentas que automatizam tarefas &lt;del&gt;chatas&lt;/del&gt; comuns de desenvolvimento. Neste artigo, vamos explorar como implementar o live reload em uma aplicação Go usando Docker e o pacote CompileDaemon.&lt;/p&gt;

&lt;p&gt;Caso só tenha interesse no código, você pode encontrar o projeto no meu &lt;a href="https://github.com/nathaliapavan/go-live-reload-docker"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é live reload?
&lt;/h2&gt;

&lt;p&gt;O live reload é uma técnica que permite que as alterações no código sejam automaticamente refletidas na aplicação em execução, sem a necessidade de reiniciar manualmente o servidor. Isso é muito útil durante o desenvolvimento, pois podemos visualizar imediatamente o impacto das alterações realizadas no código.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é CompileDaemon?
&lt;/h2&gt;

&lt;p&gt;O CompileDaemon automatiza a recompilação do código em projetos Go, eliminando a tediosa tarefa de reiniciar manualmente o servidor a cada modificação no código. Com ele, as alterações são instantaneamente refletidas na aplicação que está sendo executada, garantindo um processo de desenvolvimento mais dinâmico e eficiente. Ao combiná-lo com o Docker, criamos um ambiente de desenvolvimento onde as alterações são aplicadas sem interrupções, reduzindo o tédio e aumentando nossa produtividade.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pré-requisitos
&lt;/h2&gt;

&lt;p&gt;Antes de começarmos, certifique-se de ter as ferramentas abaixo instaladas em sua máquina:&lt;br&gt;
&lt;a href="https://go.dev/doc/"&gt;Go&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.docker.com/"&gt;Docker&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.docker.com/compose/"&gt;Docker-Compose&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Configurando o Projeto
&lt;/h2&gt;

&lt;p&gt;Vamos começar criando um novo projeto Go. Abra seu terminal e crie um diretório e navegue até ele:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;go-live-reload-docker &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;go-live-reload-docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execute o seguinte comando para inicializar o módulo do Go e criar o arquivo &lt;code&gt;go.mod&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;go mod init go-live-reload-docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Estrutura do Projeto
&lt;/h2&gt;

&lt;p&gt;Crie os arquivos abaixo manualmente. A estrutura do projeto deve ser a seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go-live-reload-docker/
├── docker-compose.yml
├── Dockerfile.dev
├── go.mod
└── main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  docker-compose.yml
&lt;/h3&gt;

&lt;p&gt;Para simplificar o processo de construção e execução da nossa aplicação, vamos utilizar o &lt;code&gt;Docker Compose&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;go-live-reload&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
      &lt;span class="na"&gt;dockerfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./Dockerfile.dev&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;8080:8080&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./:/app&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este arquivo define um serviço chamado &lt;code&gt;app&lt;/code&gt; que constrói a aplicação Go usando o arquivo &lt;code&gt;Dockerfile.dev&lt;/code&gt;. Ele também mapeia a porta &lt;code&gt;8080&lt;/code&gt; do contêiner para a porta &lt;code&gt;8080&lt;/code&gt; do host, permitindo que a aplicação seja acessível localmente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dockerfile.dev
&lt;/h3&gt;

&lt;p&gt;Este Dockerfile será usado apenas durante o desenvolvimento e incluirá o pacote &lt;code&gt;CompileDaemon&lt;/code&gt; para habilitar o live reload. Aqui está o conteúdo do arquivo Dockerfile.dev:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; golang:latest&lt;/span&gt;

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; PROJECT_DIR=/app \&lt;/span&gt;
    GO111MODULE=on \
    CGO_ENABLED=0

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="s2"&gt;"/build"&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;go get github.com/githubnemo/CompileDaemon

&lt;span class="k"&gt;RUN &lt;/span&gt;go &lt;span class="nb"&gt;install &lt;/span&gt;github.com/githubnemo/CompileDaemon

&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; CompileDaemon -build="go build -o /build/app -buildvcs=false" -command="/build/app"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este Dockerfile utiliza a imagem oficial do Go como base e define algumas variáveis de ambiente necessárias. Ele também instala o CompileDaemon e configura um ponto de entrada para executar nossa aplicação com live reload.&lt;/p&gt;

&lt;h3&gt;
  
  
  main.go
&lt;/h3&gt;

&lt;p&gt;Nosso arquivo &lt;code&gt;main.go&lt;/code&gt; contém uma simples aplicação HTTP que responde com uma mensagem. Aqui está o conteúdo do arquivo:&lt;br&gt;
&lt;/p&gt;

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

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

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HandleFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Hello, Nat!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListenAndServe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":8080"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Executando a Aplicação
&lt;/h2&gt;

&lt;p&gt;Agora que tudo está configurado, podemos construir e executar a aplicação com Docker. Basta executar os comandos na raiz do projeto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose build
docker-compose up -d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso construirá a imagem Docker e iniciará o contêiner em segundo plano. Você pode validar a aplicação em seu navegador acessando: &lt;a href="http://localhost:8080"&gt;http://localhost:8080&lt;/a&gt; 🥳&lt;/p&gt;

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

&lt;p&gt;Neste artigo, exploramos como implementar o live reload em uma aplicação Go usando Docker e CompileDaemon. O live reload  acelera o ciclo de desenvolvimento, permitindo que os desenvolvedores visualizem instantaneamente as alterações feitas no código. Com o Docker, a configuração do ambiente de desenvolvimento é simplificada e a distribuição da aplicação é facilitada. Espero que este guia tenha sido útil e que você possa aplicar esses conceitos em seus próprios projetos, será um ótimo start pra sair do zero.&lt;/p&gt;

&lt;p&gt;Até mais o/&lt;/p&gt;

&lt;h2&gt;
  
  
  Fontes
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/githubnemo/CompileDaemon"&gt;https://github.com/githubnemo/CompileDaemon&lt;/a&gt;&lt;br&gt;
&lt;a href="https://thegodev.com/live-reloading/"&gt;https://thegodev.com/live-reloading/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://blog.logrocket.com/using-air-go-implement-live-reload/"&gt;https://blog.logrocket.com/using-air-go-implement-live-reload/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://harrk.dev/live-reloading-a-go-application-with-docker/"&gt;https://harrk.dev/live-reloading-a-go-application-with-docker/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://stackoverflow.com/a/41429055"&gt;https://stackoverflow.com/a/41429055&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=EoclvPzeD14&amp;amp;ab_channel=Aregularguy"&gt;https://www.youtube.com/watch?v=EoclvPzeD14&amp;amp;ab_channel=Aregularguy&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>docker</category>
    </item>
    <item>
      <title>Arquitetura hexagonal: a sinergia dos princípios de desenvolvimento e boas práticas</title>
      <dc:creator>Nathalia Pavan</dc:creator>
      <pubDate>Thu, 11 Apr 2024 16:12:30 +0000</pubDate>
      <link>https://dev.to/nathaliapavan/arquitetura-hexagonal-a-sinergia-dos-principios-de-desenvolvimento-e-boas-praticas-3b1g</link>
      <guid>https://dev.to/nathaliapavan/arquitetura-hexagonal-a-sinergia-dos-principios-de-desenvolvimento-e-boas-praticas-3b1g</guid>
      <description>&lt;p&gt;Venhamos e convenhamos, desenvolver uma API robusta e escalável nem sempre vai ser um mar de rosas. Em meio a muitas dúvidas, linguagens, frameworks e mais uma infinidade de opções e combinações, a escolha da arquitetura certa pode fazer toda a diferença. Recentemente, enquanto iniciava um projeto pessoal, escolhi um framework &lt;em&gt;unopinionated&lt;/em&gt; pra ter mais liberdade e flexibilidade na construção da estrutura e adotei a Arquitetura Hexagonal (eu sempre me agradeço quando começo assim kkkkk).&lt;/p&gt;

&lt;p&gt;A Arquitetura Hexagonal, também conhecida como Arquitetura Ports and Adapters, visa separar as preocupações da aplicação em diferentes camadas, facilitando a manutenção, testabilidade e escalabilidade do código. Ela se baseia na ideia de que as regras de negócio devem estar no centro da aplicação, isoladas das dependências externas, como frameworks e bibliotecas.&lt;/p&gt;

&lt;p&gt;Durante o desenvolvimento, pude observar que os princípios do SOLID e os padrões de projeto (dentro do meu contexto) simplesmente surgiram de forma natural. Isso ocorre porque a arquitetura promove a separação de responsabilidades e a modularização do código, o que facilita a aplicação desses princípios e padrões.&lt;/p&gt;

&lt;p&gt;Particularmente, eu sempre fiquei preocupada pensando se minhas implementações estavam seguindo a sopa de letrinhas 😂 Essa abordagem acaba aliviando a preocupação de estar aplicando ou não esses princípios, pois uma estrutura clara, bem definida e modularizada cria um ambiente propício para esses conceitos. Não é necessário gastar energia pensando se a estrutura está bem definida, pois a própria arquitetura guia o desenvolvimento nessa direção. Acaba virando uma consequência, sabe?&lt;/p&gt;

&lt;p&gt;Outro benefício significativo e que estou curtindo muito é a facilitação dos testes unitários. A inversão de dependência promovida por esse tipo de arquietura permite que as dependências externas sejam substituídas por mocks durante os testes, facilitando a criação de casos de teste isolados. Sério, é só alegria kkkk&lt;/p&gt;

&lt;p&gt;Em resumo, ao utilizar uma arquitetura bem definida, os conceitos de SOLID e os padrões de projeto se tornam consequências naturais do processo de desenvolvimento. Não precisamos fritar o cérebro pensando explicitamente neles a todo momento, pois eles estão embutidos na própria estrutura da aplicação, são complementares.&lt;/p&gt;

&lt;p&gt;Ao iniciar um novo projeto, considere a Arquitetura Hexagonal como uma abordagem para alcançar uma base de código confiável e flexível. Isso vai permitir implementações muito mais intuitivas e fluidas, facilitando a manutenção e aprimoramento do código durante toda sua evolução. Você do futuro ficará muito grato, acredite&lt;/p&gt;

</description>
      <category>solid</category>
      <category>arquiteturahexagonal</category>
    </item>
    <item>
      <title>Diferença entre armazenamento em sessão e cache</title>
      <dc:creator>Nathalia Pavan</dc:creator>
      <pubDate>Thu, 27 Jul 2023 11:39:39 +0000</pubDate>
      <link>https://dev.to/nathaliapavan/diferenca-entre-armazenamento-em-sessao-e-cache-1bfk</link>
      <guid>https://dev.to/nathaliapavan/diferenca-entre-armazenamento-em-sessao-e-cache-1bfk</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Tanto a sessão quanto o cache são mecanismos de armazenamento temporário de dados em aplicações web, porém com propósitos diferentes.&lt;/p&gt;

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

&lt;p&gt;A sessão é uma forma de armazenar dados temporários do usuário durante uma sessão de navegação, ou seja, enquanto o usuário estiver interagindo com a aplicação. As informações armazenadas na sessão ficam disponíveis apenas para aquele usuário específico e são mantidas no servidor. As sessões são geralmente usadas para armazenar dados de login do usuário, carrinho de compras, preferências do usuário, entre outras informações que precisam ser mantidas enquanto o usuário está navegando na aplicação.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cache
&lt;/h2&gt;

&lt;p&gt;Já o cache é uma forma de armazenar dados temporários que são frequentemente acessados pela aplicação, com o objetivo de melhorar o desempenho e reduzir o tempo de resposta da aplicação. As informações armazenadas no cache são geralmente cópias de dados que foram buscados em algum lugar, como no banco de dados, e que são acessados com frequência. Quando a aplicação precisa dos dados novamente, ela verifica primeiro no cache antes de buscar nos locais originais. O cache pode ser armazenado no servidor ou no cliente, dependendo da configuração.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exemplos para sessões
&lt;/h2&gt;

&lt;p&gt;Aqui estão alguns exemplos de dados que são mais adequados para serem armazenados em sessão ao invés de cache:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Informações do usuário:&lt;/strong&gt; Quando um usuário faz login em uma aplicação web, suas informações de autenticação, como nome de usuário e senha, devem ser armazenadas em sessão para que a aplicação possa lembrar quem é o usuário durante toda a sessão de navegação.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Carrinho de compras:&lt;/strong&gt; Quando um usuário adiciona um produto ao carrinho de compras em uma loja virtual, as informações sobre o produto, como nome, preço e quantidade, devem ser armazenadas em sessão. Isso permite que o carrinho de compras acompanhe o usuário durante toda a sessão de navegação.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Preferências do usuário:&lt;/strong&gt; Se uma aplicação web permite que o usuário personalize sua experiência, como selecionar uma cor de fundo ou um idioma preferido, essas preferências devem ser armazenadas em sessão. Isso garante que as preferências do usuário sejam mantidas enquanto ele estiver navegando na aplicação.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dados sensíveis:&lt;/strong&gt; Se uma aplicação web manipula dados sensíveis, como informações médicas ou financeiras, esses dados devem ser armazenados em sessão. Isso garante que apenas o usuário autenticado tenha acesso aos dados e que eles sejam destruídos quando a sessão do usuário terminar.&lt;/p&gt;

&lt;p&gt;Esses são apenas alguns exemplos de dados que são mais adequados para serem armazenados em sessão ao invés de cache. Em geral, qualquer dado que seja específico do usuário e precise ser mantido apenas enquanto ele estiver navegando na aplicação deve ser armazenado em sessão.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exemplos para cache
&lt;/h2&gt;

&lt;p&gt;Aqui estão alguns exemplos de dados que são mais adequados para serem armazenados em cache ao invés de sessão:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dados estáticos:&lt;/strong&gt; Se uma aplicação web precisa exibir informações estáticas, como uma lista de países ou um conjunto de regras de negócio, esses dados podem ser armazenados em cache. Isso permite que a aplicação não precise buscar esses dados do banco de dados ou de outra fonte a cada requisição, melhorando assim o desempenho.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resultados de consultas:&lt;/strong&gt; Se uma aplicação web precisa realizar consultas frequentes em um banco de dados, os resultados dessas consultas podem ser armazenados em cache. Isso permite que a aplicação possa recuperar os resultados mais rapidamente nas próximas requisições, melhorando assim o desempenho.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recursos de mídia:&lt;/strong&gt; Se uma aplicação web precisa exibir imagens, vídeos ou outros recursos de mídia, esses recursos podem ser armazenados em cache. Isso permite que a aplicação não precise buscar esses recursos do servidor a cada requisição, melhorando assim o desempenho.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dados compartilhados:&lt;/strong&gt; Se uma aplicação web precisa compartilhar dados entre diferentes usuários, como uma lista de produtos disponíveis em uma loja virtual, esses dados podem ser armazenados em cache. Isso permite que a aplicação possa recuperar os dados mais rapidamente para cada usuário, melhorando assim o desempenho.&lt;/p&gt;

&lt;p&gt;Esses são apenas alguns exemplos de dados que são mais adequados para serem armazenados em cache ao invés de sessão. Em geral, qualquer dado que seja comum a vários usuários ou que possa ser compartilhado entre requisições deve ser armazenado em cache.&lt;/p&gt;

&lt;h2&gt;
  
  
  Melhores práticas
&lt;/h2&gt;

&lt;p&gt;Para armazenamento de sessões e caches, algumas boas práticas incluem:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Utilize um sistema de armazenamento seguro:&lt;/strong&gt; escolha um sistema que utilize criptografia e que tenha proteção contra ataques.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Limite o tempo de vida das sessões e caches:&lt;/strong&gt; estabeleça um tempo limite para a vida útil das sessões e caches, evitando que esses dados sejam armazenados por um tempo muito longo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Escolha um sistema de armazenamento eficiente:&lt;/strong&gt; selecione um sistema de armazenamento que seja capaz de lidar com o volume de tráfego do seu site ou aplicativo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Faça backups regulares:&lt;/strong&gt; mantenha backups das sessões e caches para evitar a perda de dados em caso de falhas do sistema.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Utilize o armazenamento em cache de forma inteligente:&lt;/strong&gt; utilize o cache para armazenar dados estáticos que não mudam com frequência, como arquivos de imagens ou estilos CSS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Limite o acesso às sessões e caches:&lt;/strong&gt; estabeleça políticas de acesso que limitem quem pode acessar as sessões e caches do sistema.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Utilize um sistema de expiração de cache:&lt;/strong&gt; utilize um sistema que defina o tempo de expiração do cache para evitar que ele armazene dados desatualizados.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Utilize técnicas de compressão de dados:&lt;/strong&gt; utilize técnicas de compressão para reduzir o tamanho dos dados armazenados em sessões e caches, economizando espaço e melhorando o desempenho do sistema.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prós e Contras
&lt;/h2&gt;

&lt;p&gt;A melhor forma de armazenamento depende de vários fatores, como a frequência de atualização das configurações, o tempo necessário para buscar as informações da API externa e a sensibilidade das informações. Aqui estão alguns prós e contras de cada opção de armazenamento para ajudar na sua decisão.&lt;/p&gt;

&lt;h3&gt;
  
  
  Armazenamento em cache
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Prós&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Melhora o desempenho da aplicação, pois os dados ficam armazenados em memória e podem ser acessados rapidamente;&lt;/li&gt;
&lt;li&gt;Reduz a carga na API externa, pois as informações são recuperadas do cache em vez de serem solicitadas repetidamente;&lt;/li&gt;
&lt;li&gt;Pode ser configurado para expirar após um determinado período de tempo ou quando ocorrerem atualizações das configurações na API externa, garantindo que as informações estejam atualizadas;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Contras&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Se as configurações forem atualizadas com frequência na API externa, o cache pode não ser eficaz e pode ser necessário atualizar as informações com mais frequência;&lt;/li&gt;
&lt;li&gt;As informações podem não estar disponíveis imediatamente após uma atualização, já que as informações do cache precisam ser atualizadas manualmente ou quando expirarem.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Armazenamento em sessão&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Prós&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Garante que as informações sejam atualizadas em tempo real, já que as informações são buscadas da API externa a cada nova sessão;&lt;/li&gt;
&lt;li&gt;Permite personalização individual para cada usuário;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Contras&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pode afetar o desempenho da aplicação se muitos usuários estiverem acessando a mesma API externa ao mesmo tempo;&lt;/li&gt;
&lt;li&gt;Pode aumentar o tempo de carregamento da página para o usuário, já que as informações precisam ser buscadas da API externa a cada nova sessão;&lt;/li&gt;
&lt;li&gt;Pode ser necessário um tempo de sessão muito curto para garantir que as informações sejam atualizadas com frequência, o que pode levar a uma experiência de usuário ruim.&lt;/li&gt;
&lt;li&gt;Em geral, se as configurações são atualizadas com frequência na API externa e as informações são sensíveis, é melhor armazená-las em sessão para garantir que elas sejam sempre atualizadas. Se as informações não são sensíveis e as atualizações são raras, o armazenamento em cache pode ser mais adequado para melhorar o desempenho da aplicação. No entanto, é importante avaliar cuidadosamente cada caso e considerar os prós e contras antes de tomar uma decisão.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Em resumo, a principal diferença entre sessão e cache é que a sessão é usada para armazenar dados temporários do usuário durante uma sessão de navegação, enquanto o cache é usado para armazenar dados temporários frequentemente acessados pela aplicação, visando melhorar o desempenho.&lt;/p&gt;

&lt;p&gt;É claro que isso aqui é apenas a lasquinha do iceberg, podemos aprofundar muito mais principalmente nas responsabilidades front e back.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fontes
&lt;/h2&gt;

&lt;p&gt;Aqui estão algumas fontes que você pode consultar para aprender mais sobre o armazenamento em sessão e cache:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Artigo de Alexander Nnakwue, disponível em LogRocket:&lt;/strong&gt; &lt;a href="https://blog.logrocket.com/caching-node-js-optimize-app-performance/"&gt;Caching in Node.js to optimize app performance&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Artigo de Joseph Chege, disponível em OpenReplayBlog:&lt;/strong&gt; &lt;a href="https://blog.openreplay.com/sessions-management-and-authentication-with-node/"&gt;Understanding Sessions Management And Authentication With Node.Js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Artigo do Blog da AWS sobre cache em aplicações web, disponível em:&lt;/strong&gt; &lt;a href="https://aws.amazon.com/pt/caching/"&gt;https://aws.amazon.com/pt/caching/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Livro "High Performance Web Sites" de Steve Souders&lt;/strong&gt;, que aborda técnicas de otimização de desempenho, incluindo o uso de cache: &lt;a href="https://www.oreilly.com/library/view/high-performance-web/9780596529307/"&gt;High Performance Web Sites [BOOK]&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cache</category>
      <category>session</category>
    </item>
    <item>
      <title>Aumentando a Produtividade com o Class-Validator no DTO do NestJS</title>
      <dc:creator>Nathalia Pavan</dc:creator>
      <pubDate>Thu, 20 Jul 2023 23:26:39 +0000</pubDate>
      <link>https://dev.to/nathaliapavan/aumentando-a-produtividade-com-o-class-validator-no-dto-do-nestjs-1pgh</link>
      <guid>https://dev.to/nathaliapavan/aumentando-a-produtividade-com-o-class-validator-no-dto-do-nestjs-1pgh</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;No mundo acelerado do desenvolvimento de software, ser produtivo é crucial. Reduzir o tempo gasto na escrita de código repetitivo e de validação de dados pode ser uma tarefa desafiadora. Felizmente, o NestJS, um popular framework para construção de aplicações Node.js, oferece uma solução chic para esse problema - o &lt;strong&gt;class-validator&lt;/strong&gt;. Neste artigo, exploraremos como o class-validator pode ser utilizado no DTO (Data Transfer Object) do NestJS, proporcionando uma maneira fácil e eficiente de validar os dados recebidos e, assim, aumentar sua produtividade.&lt;br&gt;
&lt;a href="https://i.giphy.com/media/pT4pmRFs15Yg8/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/pT4pmRFs15Yg8/giphy.gif" alt="Alt Text" width="320" height="192"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  O que é o Class-Validator
&lt;/h2&gt;

&lt;p&gt;O class-validator é uma biblioteca de validação para classes em TypeScript. Ele fornece uma maneira declarativa de definir as regras de validação, eliminando a necessidade de escrever manualmente. Essa biblioteca é extremamente útil no contexto do NestJS, pois pode ser integrada perfeitamente aos DTOs usados para transferir dados entre as camadas da aplicação.&lt;/p&gt;

&lt;p&gt;Github do projeto class-validator: &lt;a href="https://github.com/typestack/class-validator"&gt;https://github.com/typestack/class-validator&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esse pacote não é específico no NestJS, mas resolvi escrever esse artigo com o framework pois sou modinha e no momento ele está me fazendo muito feliz a cada descoberta kkkkkk Se você gostar tanto como eu, poderá implementar facilmente em qualquer aplicação escrita em Typescript.&lt;/p&gt;
&lt;h2&gt;
  
  
  Benefícios do Class-Validator no DTO do NestJS
&lt;/h2&gt;

&lt;p&gt;Ao utilizar o class-validator no DTO do NestJS, teremos benefícios significativos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Redução do código repetitivo: O class-validator permite definir as regras de validação diretamente nas propriedades do DTO, eliminando a necessidade de escrever funções de validação separadas para cada campo. Isso reduz drasticamente a quantidade de código repetitivo, tornando a manutenção e evolução do código muito mais fácil.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Melhor legibilidade: Ao declarar as regras de validação diretamente no DTO, o código se torna mais legível e autoexplicativo. As regras de validação ficam intimamente ligadas às propriedades correspondentes, tornando o código mais compreensível para outros desenvolvedores.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Validações pré-definidas: O class-validator oferece uma infinidade de validações pré-definidas, como validação de tipo, validação de tamanho mínimo/máximo, validação de formato de e-mail, entre outras. Essas validações podem ser facilmente aplicadas às propriedades do DTO com o uso de decoradores, poupando tempo e esforço.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Validações personalizadas: Além das validações pré-definidas, o class-validator permite a criação de validações personalizadas para atender às necessidades específicas da aplicação. Isso nos dá uma flexibilidade adicional para lidar com casos de validação mais complexos e específicos do domínio.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/MypFo3No7gHLywrjrM/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/MypFo3No7gHLywrjrM/giphy.gif" alt="Alt Text" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Exemplo prático
&lt;/h2&gt;

&lt;p&gt;Vamos implementar um exemplo onde temos uma API de criação de postagens em um blog. Para criar uma nova postagem, precisamos garantir que o título seja uma string com no mínimo 5 caracteres e que o conteúdo da postagem não esteja vazio. Além disso, cada postagem pode ter uma lista de tags associadas a ela. Veja o exemplo:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Post&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;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;IsString&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MinLength&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IsNotEmpty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IsArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ArrayNotEmpty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ArrayMaxSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ArrayUnique&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;class-validator&lt;/span&gt;&lt;span class="dl"&gt;'&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;CreatePostDto&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;IsString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;MinLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;title&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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;IsString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;IsNotEmpty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;content&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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;IsArray&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ArrayNotEmpty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ArrayMaxSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ArrayUnique&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;tags&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="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostsController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nf"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;createPostDto&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CreatePostDto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Restante da lógica para criar a postagem&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;No exemplo acima, temos o DTO CreatePostDto, que possui as propriedades title, content e tags. Utilizamos decorators específicos para cada propriedade:&lt;/p&gt;

&lt;p&gt;Para o &lt;code&gt;title&lt;/code&gt;, utilizamos:&lt;br&gt;
@IsString() para garantir que seja uma string;&lt;br&gt;
@MinLength(5) para exigir um mínimo de 5 caracteres no título.&lt;/p&gt;

&lt;p&gt;Para o &lt;code&gt;content&lt;/code&gt;, utilizamos:&lt;br&gt;
@IsString() para garantir que seja uma string;&lt;br&gt;
@IsNotEmpty() para garantir que não esteja vazio.&lt;/p&gt;

&lt;p&gt;Para as &lt;code&gt;tags&lt;/code&gt;, utilizamos uma série de decorators para validar a lista de tags:&lt;br&gt;
@IsArray() para garantir que seja um array;&lt;br&gt;
@ArrayNotEmpty() para garantir que não esteja vazio;&lt;br&gt;
@ArrayMaxSize(5) para limitar o tamanho máximo do array em 5 elementos;&lt;br&gt;
@ArrayUnique() para garantir que não haja valores duplicados na lista.&lt;/p&gt;

&lt;p&gt;Assim, ao receber uma requisição no endpoint de criação de postagens, o NestJS aplicará as regras de validação definidas no DTO CreatePostDto. Se algum dos campos não atender às regras de validação, uma resposta de erro será retornada automaticamente.&lt;/p&gt;

&lt;p&gt;O uso do Class Validator nesse contexto permite garantir que os dados de entrada atendam aos critérios estabelecidos para a criação de uma postagem, como o tamanho mínimo do título, a presença de conteúdo e a validação das tags associadas à postagem. Isso contribui para a integridade dos dados, a consistência das informações em sua API e felicidade do time hehe&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/10UeedrT5MIfPG/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/10UeedrT5MIfPG/giphy.gif" alt="Alt Text" width="500" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se você não estiver utilizando o Class Validator, precisará implementar as verificações de validação manualmente em seu código. Aqui está um exemplo de como você poderia realizar as mesmas validações sem o uso do Class Validator:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Post&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="nx"&gt;BadRequestException&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/common&lt;/span&gt;&lt;span class="dl"&gt;'&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;CreatePostDto&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;title&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="nl"&gt;content&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="nl"&gt;tags&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="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostsController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nf"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;createPostDto&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CreatePostDto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;createPostDto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;createPostDto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5&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;BadRequestException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;O título deve ser uma string com no mínimo 5 caracteres&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="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="nx"&gt;createPostDto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;createPostDto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&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="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BadRequestException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;O conteúdo da postagem não pode estar vazio&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="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="nx"&gt;createPostDto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createPostDto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;createPostDto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&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;BadRequestException&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 lista de tags deve ser um array não vazio&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;uniqueTags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createPostDto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uniqueTags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;createPostDto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&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;BadRequestException&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 lista de tags não pode conter valores duplicados&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createPostDto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&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;BadRequestException&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 lista de tags não pode ter mais do que 5 elementos&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="c1"&gt;// Restante da lógica para criar a postagem&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;Nesse exemplo, dentro do método createPost, você realiza manualmente as verificações de validação para o DTO CreatePostDto.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/6Q3M4BIK0lX44/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/6Q3M4BIK0lX44/giphy.gif" alt="Alt Text" width="360" height="235"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para o campo title, você verifica se ele existe e se possui pelo menos 5 caracteres.&lt;br&gt;
Para o campo content, você verifica se ele existe e se não está vazio, removendo espaços em branco extras.&lt;br&gt;
Para o campo tags, você verifica se ele existe, é um array não vazio, não possui valores duplicados e tem no máximo 5 elementos.&lt;br&gt;
Se alguma das verificações falhar, você pode lançar uma exceção adequada (como BadRequestException no NestJS) para indicar que a validação falhou e retornar uma resposta de erro.&lt;/p&gt;

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

&lt;p&gt;Embora seja possível realizar as validações manualmente, o uso do Class Validator simplifica o processo e fornece uma abordagem declarativa e consistente para validar objetos. Com validações pré-definidas e personalizadas, ele também oferece recursos adicionais, como mensagens de erro customizadas e validação de objetos aninhados. Portanto, o Class Validator pode ser uma opção mais produtiva e conveniente para lidar com a validação em suas APIs.&lt;/p&gt;

&lt;p&gt;Espero que esse singelo artigo tenha demonstrado como o uso do class-validator no DTO do NestJS pode melhorar a produtividade e facilitar suas implementações no dia a dia. Ao utilizar essa abordagem em seus projetos, você estará agilizando o desenvolvimento e garantindo a integridade dos dados recebidos. Experimente em seu próximo projeto!&lt;/p&gt;

&lt;p&gt;Obrigada por ler até aqui :D&lt;br&gt;
&lt;a href="https://i.giphy.com/media/3coysfsJSiqW3J3Xzm/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3coysfsJSiqW3J3Xzm/giphy.gif" alt="Alt Text" width="480" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>productivity</category>
      <category>dto</category>
      <category>backend</category>
    </item>
    <item>
      <title>Initial Commit</title>
      <dc:creator>Nathalia Pavan</dc:creator>
      <pubDate>Wed, 07 Oct 2020 03:16:18 +0000</pubDate>
      <link>https://dev.to/nathaliapavan/initial-commit-3p9j</link>
      <guid>https://dev.to/nathaliapavan/initial-commit-3p9j</guid>
      <description>&lt;p&gt;Hello World!&lt;/p&gt;

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