<?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: Bruno Mestres</title>
    <description>The latest articles on DEV Community by Bruno Mestres (@brunomestres).</description>
    <link>https://dev.to/brunomestres</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%2F1201765%2Fc32ea846-ebd6-45b2-bb73-f191e51a7ea4.jpeg</url>
      <title>DEV Community: Bruno Mestres</title>
      <link>https://dev.to/brunomestres</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/brunomestres"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>Bruno Mestres</dc:creator>
      <pubDate>Thu, 27 Feb 2025 02:53:18 +0000</pubDate>
      <link>https://dev.to/brunomestres/-59d4</link>
      <guid>https://dev.to/brunomestres/-59d4</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/brunomestres" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuser%2Fprofile_image%2F1201765%2Fc32ea846-ebd6-45b2-bb73-f191e51a7ea4.jpeg" alt="brunomestres"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/brunomestres/como-rodar-uma-api-nodejs-postgresql-com-docker-41di" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;🚀 Como Rodar uma API Node.js + PostgreSQL com Docker&lt;/h2&gt;
      &lt;h3&gt;Bruno Mestres ・ Feb 26&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#docker&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#node&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#postgres&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>docker</category>
      <category>node</category>
      <category>postgres</category>
    </item>
    <item>
      <title>🚀 Como Rodar uma API Node.js + PostgreSQL com Docker</title>
      <dc:creator>Bruno Mestres</dc:creator>
      <pubDate>Wed, 26 Feb 2025 20:53:18 +0000</pubDate>
      <link>https://dev.to/brunomestres/como-rodar-uma-api-nodejs-postgresql-com-docker-41di</link>
      <guid>https://dev.to/brunomestres/como-rodar-uma-api-nodejs-postgresql-com-docker-41di</guid>
      <description>&lt;p&gt;Hoje, vou compartilhar um exemplo prático e direto para quem quer aprender Docker: subir uma API Node.js conectada ao PostgreSQL sem precisar instalar o banco localmente.&lt;/p&gt;

&lt;p&gt;Se você já perdeu tempo configurando dependências no seu ambiente ou precisa garantir que tudo funcione igual em qualquer máquina, Docker é a solução!&lt;/p&gt;

&lt;p&gt;📌 Estruturando o Projeto&lt;br&gt;
Criamos dois containers:&lt;br&gt;
🔹 App Node.js para servir uma API&lt;br&gt;
🔹 Banco PostgreSQL para armazenar os dados&lt;/p&gt;

&lt;p&gt;&lt;code&gt;📦 meu-projeto-docker&lt;br&gt;
 ┣ 📂 src&lt;br&gt;
 ┃ ┣ 📜 main.ts&lt;br&gt;
 ┣ 📜 Dockerfile&lt;br&gt;
 ┣ 📜 docker-compose.yml&lt;br&gt;
 ┣ 📜 package.json&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
1️⃣ Criando a API Node.js&lt;br&gt;
Dentro do projeto, inicialize o package.json:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instale as dependências:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install express pg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, crie src/main.ts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import express from "express";
import pg from 'pg'
const { Pool } = pg
const app = express();

const pool = new Pool({
  user: "postgres",
  host: "db",
  database: "meubanco",
  password: "postgres",
  port: 5432,
});

app.get("/", async (req, res) =&amp;gt; {
  const response = await pool.query("SELECT NOW()");

  res.send(`Banco conectado! Hora atual: ${response.rows[0].now}`);
});



app.listen(3000, () =&amp;gt; console.log("API running on port 3000"));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2️⃣ Criando o Dockerfile&lt;/p&gt;

&lt;p&gt;Esse arquivo define a imagem da nossa API:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Dockerfile&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;FROM node:23
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "src/main.ts"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3️⃣ Configurando o Docker Compose&lt;/p&gt;

&lt;p&gt;Aqui criamos os serviços da API e do PostgreSQL.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker-compose.yml&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;version: "3.8"

services:
  db:
    image: postgres:15
    restart: always
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: meubanco
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data

  app:
    build: .
    restart: always
    depends_on:
      - db
    ports:
      - "3000:3000"
    volumes:
      - .:/app

volumes:
  pgdata:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4️⃣ Rodando o Projeto 🚀&lt;/p&gt;

&lt;p&gt;Agora é só rodar:&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 up -d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E acessar a API em:&lt;br&gt;
&lt;code&gt;http://localhost:3000&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Enfim, com Docker, garantimos que nosso ambiente seja consistente, evitando aqueles famosos "na minha máquina funciona".&lt;/p&gt;

&lt;p&gt;Esse foi só o começo! Podemos evoluir esse setup com migrations, CI/CD e Kubernetes. Se quiser mais conteúdos como esse, comenta aí! 👇🔥&lt;/p&gt;

</description>
      <category>docker</category>
      <category>node</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Construindo uma API segura e eficiente com @fastify/jwt e @fastify/mongodb</title>
      <dc:creator>Bruno Mestres</dc:creator>
      <pubDate>Mon, 13 Jan 2025 22:14:10 +0000</pubDate>
      <link>https://dev.to/brunomestres/construindo-uma-api-segura-e-eficiente-com-fastifyjwt-e-fastifymongodb-1fck</link>
      <guid>https://dev.to/brunomestres/construindo-uma-api-segura-e-eficiente-com-fastifyjwt-e-fastifymongodb-1fck</guid>
      <description>&lt;p&gt;Ultimamente tenho utilizado bastante o Fastify em meus projetos pessoais, recentemente descobri diversas funcionalidades através de plugins oficiais.&lt;/p&gt;

&lt;p&gt;Eles são leves, eficientes e, o melhor de tudo, encaixam perfeitamente no ecossistema do Fastify.&lt;/p&gt;

&lt;p&gt;Então resolvi criar um projeto prático com autenticação e persistência, utilizando o JWT e o MongoDB.&lt;/p&gt;

&lt;p&gt;Plugins usados no projeto: &lt;/p&gt;

&lt;p&gt;⚒️ O @fastify/jwt é um plugin oficial que simplifica a autenticação com JSON Web Tokens. Com ele, dá pra:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gerar tokens JWT de forma rápida.&lt;/li&gt;
&lt;li&gt;Verificar tokens automaticamente nas rotas protegidas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⚒️ @fastify/mongodb: Plugin oficial do Fastify para integração com o banco de dados MongoDB.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ele se encarrega de gerenciar a conexão com o MongoDB de forma eficiente, sem que eu precise ficar configurando drivers manualmente.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Os plugins seguem uma interface padrão. Basta registrá-los com fastify.register(), definir algumas configurações e pronto.&lt;/p&gt;

&lt;p&gt;Depois disso posso, acessar o banco diretamente com fastify.mongo e o módulo do jwt com o fastify.jwt.&lt;/p&gt;

&lt;p&gt;Também criei um decorator para anexar apenas as rotas que seriam protegidas, onde ele verificará o token passado no cabeçalho.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Fastify from "fastify";
import mongodb from "@fastify/mongodb";
import jwt from "@fastify/jwt";
import { config } from "./constants.ts";
import * as bcrypt from "bcrypt";

const fastify = Fastify();

type RequestUser = {
  username: string;
  email: string;
  password: string;
};

fastify.register(mongodb, {
  forceClose: true,
  url: config.MONGO_URL,
});

fastify.register(jwt, {
  secret: "supersecret",
});

fastify.post("/signup", async (req, reply) =&amp;gt; {
  const salt = 10;
  const { email, password, username } = req.body as RequestUser;

  const data = {
    username,
    email,
    password: await bcrypt.hash(password, salt),
  };

  const user = await fastify.mongo.client.db("plugins").collection("users").insertOne(data);

  reply.send({ user })
});

fastify.decorate("auth", async (request, reply) =&amp;gt; {
  try {
    await request.jwtVerify();
  } catch (err) {
    reply.send(err);
  }
});

fastify.post("/signin", (req, reply) =&amp;gt; {
  // some code
  const body = req.body;
  const token = fastify.jwt.sign({ body });
  console.log(token);
  reply.send({ token });
});

fastify.get("/", { onRequest: [fastify.auth] }, async (req, reply) =&amp;gt; {
  const users = fastify.mongo?.client.db("plugins").collection("users").find();

  const data: any = [];

  for await (const doc of users) {
    data.push(doc);
  }
  return data;
});

fastify.listen({ port: 3333 }, (err) =&amp;gt; {
  if (err) process.exit(1);

  console.log("Running server");
});

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

&lt;/div&gt;



</description>
      <category>node</category>
      <category>backend</category>
      <category>api</category>
      <category>mongodb</category>
    </item>
    <item>
      <title>Design Pattern - Strategy</title>
      <dc:creator>Bruno Mestres</dc:creator>
      <pubDate>Mon, 18 Mar 2024 13:52:30 +0000</pubDate>
      <link>https://dev.to/brunomestres/design-pattern-strategy-4dff</link>
      <guid>https://dev.to/brunomestres/design-pattern-strategy-4dff</guid>
      <description>&lt;p&gt;Ultimamente tenho estudado bastante padrões de projetos, então resolvi escrever um pouco sobre alguns, e decidi começar pelo Strategy.&lt;/p&gt;

&lt;p&gt;O Strategy é um padrão de projeto da categoria comportamental, que permite que você crie uma hierarquia de algoritmos, separando os objetos intercambiáveis em classes separadas.&lt;br&gt;
Esse padrão é muito útil quando temos um código carregado de condições, ele permite que nosso código se adapte a diversas situações que venha acontecer posteriormente. &lt;/p&gt;

&lt;p&gt;Digamos que tenham algumas regras de negocio para dar desconto em um Ecommerce, e ela varia dependendo de diversos fatores, como quantidade de produtos no carrinho, ou um determinado valor a ser batido, promoções e etc. Nesse caso a classe que representa o carrinho de compra teria que verificar cada uma dessas variantes com diversos IFS e aplicar o valor correto, e a medida que mais opções de desconto fosse adicionado na regra de negocio, teríamos que mexer na classe do carrinho, tornando o código cada vez mais difícil de se manter e aumentando a chance de criar bugs em códigos que já estavam funcionando.&lt;/p&gt;

&lt;p&gt;O Strategy sugere que nesse caso, pegue a classe que tem diversos IFS e separe os códigos em outras classes separadas, chamadas de estratégias. &lt;/p&gt;

&lt;p&gt;Na estrutura desse Padrão temos:&lt;br&gt;
    O contexto e a classe que contem o algoritmo com a lógica comum, ela vem carregada de condições.&lt;br&gt;
    A interface da Strategy, que define a função que as estratégias deverão executar.&lt;br&gt;
    E as estratégias que são os algoritmos específicos para cada situação que o código cliente chamar. &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%2F1hc88w9y7bf2z70ni2jh.jpg" 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%2F1hc88w9y7bf2z70ni2jh.jpg" alt="Image description" width="661" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>designpatterns</category>
      <category>strategy</category>
      <category>developer</category>
    </item>
  </channel>
</rss>
