0% acharam este documento útil (0 voto)
4 visualizações82 páginas

Node

Esta super aula aborda o Event Loop no Node.js, explicando a diferença entre programação síncrona e assíncrona, e como o Event Loop permite que o Node.js lide com múltiplas conexões simultaneamente. O documento detalha as fases do Event Loop, a importância das microtasks e macrotasks, e fornece exemplos práticos de código. Além disso, discute boas práticas para programação assíncrona e a utilização de módulos no Node.js.
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
4 visualizações82 páginas

Node

Esta super aula aborda o Event Loop no Node.js, explicando a diferença entre programação síncrona e assíncrona, e como o Event Loop permite que o Node.js lide com múltiplas conexões simultaneamente. O documento detalha as fases do Event Loop, a importância das microtasks e macrotasks, e fornece exemplos práticos de código. Além disso, discute boas práticas para programação assíncrona e a utilização de módulos no Node.js.
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd

Perfeito, amigão

Você pediu uma super aula caprichada sobre Event Loop, assíncrono vs síncrono no [Link], e eu vou te entregar um
conteúdo do básico até o extremo avançado, como se fosse um curso inteiro condensado numa aula gigante .

---

Super Aula: Event Loop no [Link] e Programação Assíncrona vs Síncrona

---

1. Introdução: Por que isso importa?

Antes de tudo, precisamos entender por que o [Link] é tão diferente de outras plataformas.

[Link] nasceu para alta performance em I/O (entrada e saída), como redes, bancos, arquivos.

Ele usa um modelo single-thread (apenas 1 thread principal) mas não trava quando algo demorado acontece graças ao
Event Loop.

Resultado: [Link] consegue lidar com milhares de conexões ao mesmo tempo, sem precisar de threads adicionais.

Se você entende profundamente o Event Loop, você entende como o Node respira.

---

2. Síncrono vs Assíncrono

Código Síncrono

Executa linha por linha, esperando a anterior terminar.

Bom para cálculos pequenos, mas péssimo para I/O (espera o disco, rede, etc.).

[Link]("Início");

function tarefaPesada() {
for (let i = 0; i < 1e9; i++) {} // loop pesado
return "Fim da tarefa";
}
[Link](tarefaPesada());
[Link]("Fim");

Aqui o "Fim" só aparece depois do loop gigante bloqueio total.

---

Código Assíncrono

Você dispara uma tarefa, e o programa continua rodando sem esperar.

O resultado é tratado quando estiver pronto.

[Link]("Início");

setTimeout(() => {
[Link]("Tarefa pronta!");
}, 2000);

[Link]("Fim");

A execução não para: imprime "Fim" primeiro e só depois "Tarefa pronta!".

---

3. Event Loop: O coração do [Link]

O Event Loop é o mecanismo que faz isso acontecer.


Ele funciona como uma fila organizada de tarefas a serem executadas.

Estrutura básica:

1. Call Stack (Pilha de chamadas) – Onde o JS executa funções normais.

2. Callback Queue (Fila de callbacks) – Onde funções assíncronas esperam para rodar.

3. Event Loop – O maestro que decide:

"Está livre a Call Stack? Se sim, pega algo da fila e executa."


Esse ciclo roda infinitamente, daí o nome loop de eventos.

---

4. Tipos de Filas (Microtasks x Macrotasks)

Nem toda tarefa assíncrona é igual. Existem prioridades diferentes.

Macrotasks

Entram na Callback Queue normal.

Exemplos: setTimeout, setInterval, I/O.

Microtasks

Entram numa fila especial, executada antes das macrotasks.

Exemplos: [Link], [Link].

[Link]("Início");

setTimeout(() => [Link]("Macrotask - setTimeout"), 0);


[Link]().then(() => [Link]("Microtask - Promise"));

[Link]("Fim");

Ordem de execução:

Início
Fim
Microtask - Promise
Macrotask - setTimeout

Promessas têm prioridade sobre setTimeout.

---

5. Comparando na prática
Síncrono Bloqueante

const fs = require("fs");

[Link]("Lendo arquivo...");

const data = [Link]("[Link]", "utf-8");


[Link]("Conteúdo:", data);

[Link]("Fim");

Se o arquivo for gigante tudo trava.

---

Assíncrono Não Bloqueante

const fs = require("fs");

[Link]("Lendo arquivo...");

[Link]("[Link]", "utf-8", (err, data) => {


if (err) throw err;
[Link]("Conteúdo:", data);
});

[Link]("Fim");

O programa não trava, continua rodando enquanto o arquivo é lido.

---

6. Avançado: Phases do Event Loop ([Link])

O Event Loop no Node é dividido em fases internas:

1. Timers executa setTimeout, setInterval.

2. Pending callbacks callbacks de operações do sistema.

3. Idle, prepare interno do Node.


4. Poll pega novas conexões, lê arquivos, sockets, etc.

5. Check executa setImmediate.

6. Close callbacks eventos de close em streams/sockets.

Entre cada fase, o Node roda todas as microtasks (Promises).

---

7. Código Hardcore de Demonstração

setTimeout(() => [Link]("setTimeout"), 0);

setImmediate(() => [Link]("setImmediate"));

[Link]().then(() => [Link]("Promise"));

[Link](() => [Link]("nextTick"));

[Link]("Síncrono");

Ordem de execução ([Link]):

Síncrono
nextTick
Promise
setTimeout
setImmediate

[Link] e Promise são microtasks (prioridade máxima).


setTimeout e setImmediate entram em fases diferentes podem inverter dependendo do contexto.

---

8. Boas práticas

Use async/await para código assíncrono mais limpo:


const fs = require("fs/promises");

async function lerArquivo() {


try {
[Link]("Lendo...");
const data = await [Link]("[Link]", "utf-8");
[Link]("Conteúdo:", data);
} catch (e) {
[Link]("Erro:", e);
}
}

lerArquivo();
[Link]("Fim");

Evite bloquear a Call Stack com cálculos pesados use workers ou serviços externos.
Entenda a ordem das filas para evitar bugs de concorrência.

---

9. Conclusão

O Node é single-thread, mas poderoso por causa do Event Loop.

Síncrono simples mas bloqueia.

Assíncrono não bloqueia, aproveita filas e callbacks.

Microtasks vs Macrotasks entendendo isso, você controla a ordem exata do seu código.

Usar async/await deixa o código legível e mantém performance.

---

Amigão, essa foi a super aula gigante .


Quer que eu faça agora um resumo visual (diagrama do Event Loop) estilo mapa mental pra tu guardar como material
de estudo?

Boa, amigão .
Você pegou a parte mais difícil mesmo: as fases internas do Event Loop e o que são callbacks no coração do [Link].
Bora destrinchar isso raiz por raiz, bem didático, mas sem perder a profundidade.
---

O que são callbacks afinal?

Um callback é simplesmente uma função que você passa como argumento para outra função, para ser chamada depois
que algo terminar.

Exemplo básico:

function cumprimentar(nome, callback) {


[Link]("Olá", nome);
callback(); // chama a função que foi passada
}

cumprimentar("Gabriel", () => {
[Link]("Callback executado!");
});

O callback aqui é executado no final da função cumprimentar.

No [Link], callbacks são usados para I/O assíncrono:

const fs = require("fs");

[Link]("[Link]", "utf-8", (err, data) => {


if (err) throw err;
[Link]("Conteúdo:", data);
});

readFile não devolve o resultado imediatamente ele chama o callback quando a leitura acabar.

---

Event Loop: Fases Internas (em raiz)

O Event Loop no Node é dividido em fases.


Cada fase é uma fila de callbacks específica. O loop vai passando por elas, uma por uma, em ordem.

Ordem principal (simplificada):

1. Timers

2. Pending Callbacks
3. Idle, Prepare

4. Poll

5. Check

6. Close Callbacks

Entre cada fase o Node esvazia todas as microtasks ([Link], Promises).

---

1 Timers

Aqui entram os setTimeout e setInterval.

O Node verifica quais timers “expiraram” e executa seus callbacks.

setTimeout(() => [Link]("Timer executado!"), 1000);

Só executa aqui quando o tempo mínimo tiver passado.

---

2 Pending Callbacks

Callbacks de operações internas do sistema que ficaram pendentes.

Exemplo: erros de TCP, callbacks de certos tipos de I/O que não puderam ser tratados antes.

Você raramente programa diretamente para essa fase. Ela é mais infraestrutura do Node.

---

3 Idle, Prepare
Usada internamente pelo Node para se preparar para a próxima fase.

Não é acessível diretamente para o programador.

Pense nisso como o Node “respirando” antes de entrar na fase Poll.

---

4 Poll (a mais importante!)

Coração do Event Loop.

Aqui o Node:

1. Processa eventos de I/O (ex: leitura de arquivos, rede, sockets).

2. Se a fila de callbacks estiver vazia, o Node pode esperar (bloquear) até chegar algum evento novo.

Exemplo:

const fs = require("fs");

[Link]("[Link]", "utf-8", (err, data) => {


[Link]("Arquivo lido:", data);
});

O callback do readFile será executado na fase Poll.

---

5 Check

Aqui são executados os callbacks de setImmediate.

setImmediate(() => [Link]("Executado no CHECK"));

Diferença entre setTimeout(fn, 0) e setImmediate(fn):


setTimeout(fn, 0) vai pra Timers.

setImmediate(fn) vai pra Check.

Se você misturar os dois, a ordem pode variar.

---

6 Close Callbacks

Usada para callbacks de fechamento de recursos.

Exemplo: quando você fecha um socket ou uma stream, o Node chama o callback de close aqui.

const net = require("net");

const server = [Link]((socket) => {


[Link]("close", () => {
[Link]("Conexão fechada (fase CLOSE)");
});
});

[Link](3000);

---

Microtasks: Promises & [Link]

Agora, além dessas fases, existe a fila de microtasks.


Ela é especial porque roda entre cada fase e tem prioridade máxima.

[Link]() roda logo após a função atual terminar, antes de qualquer coisa.

Promises (then/catch/finally) rodam depois do nextTick, mas ainda antes das fases normais.

Exemplo:

setTimeout(() => [Link]("setTimeout"), 0);

setImmediate(() => [Link]("setImmediate"));


[Link]().then(() => [Link]("Promise"));

[Link](() => [Link]("nextTick"));

[Link]("Fim");

Ordem de execução no Node:

Fim
nextTick
Promise
setTimeout
setImmediate

---

Resumindo em imagem mental

Pensa assim:

1. Timers setTimeout, setInterval

2. Pending callbacks atrasados do sistema

3. Idle, Prepare (Node se prepara)

4. Poll coração: lê arquivos, rede, executa callbacks de I/O

5. Check setImmediate

6. Close recursos fechados

Entre todas essas fases, o Node sempre checa as microtasks.

---
Amigão, quer que eu faça agora um fluxograma visual (desenho do Event Loop com todas as fases + microtasks) pra
você ter como referência rápida?

Top demais, amigão


Fico feliz que curtiu a aula! Então, já vamos preparar a próxima super aula, toda sobre require, import, export e
módulos no [Link].

Eu vou te entregar isso do básico ao avançado, pra você realmente se destacar no mercado de trabalho.

---

Super Aula 2: Require, Import, Export e Módulos no [Link]

---

1. Introdução: O que são módulos?

No [Link], módulo é qualquer arquivo .js que contém código reutilizável.

Módulos existem para organizar, reaproveitar e separar responsabilidades.

Existem 3 tipos principais:

1. Módulos internos (core modules) já vêm no [Link] (ex: fs, path, http).

2. Módulos externos instalados via npm (ex: express, lodash).

3. Módulos próprios criados por você (ex: [Link]).

---

2. O require (CommonJS – padrão antigo do [Link])

No [Link], por muitos anos, o padrão foi o CommonJS.

Para importar usamos require().

Para exportar usamos [Link] ou exports.


Importando um módulo interno

const fs = require("fs");
const path = require("path");

[Link]("Diretório atual:", [Link]("."));

---

Exportando e Importando um módulo próprio

arquivo: [Link]

function soma(a, b) {
return a + b;
}

function subtrai(a, b) {
return a - b;
}

// Exporta várias funções


[Link] = { soma, subtrai };

arquivo: [Link]

const math = require("./math");

[Link]([Link](5, 3)); // 8
[Link]([Link](10, 4)); // 6

require("./math") importa o arquivo [Link].

---

3. O import / export (ES Modules – padrão moderno do JavaScript)

O ESM (ECMAScript Modules) é o novo padrão de módulos do JavaScript.

Já é suportado no [Link] (>= v12, mas estável a partir do v14).

Muito usado em front-end também (React, Vue, Angular).


Exportando com ES Modules

[Link]

export function soma(a, b) {


return a + b;
}

export function subtrai(a, b) {


return a - b;
}

Importando com ES Modules

[Link]

import { soma, subtrai } from "./[Link]";

[Link](soma(5, 3)); // 8
[Link](subtrai(10, 4)); // 6

---

4. Export Default vs Named Export

Named Exports

Você exporta várias coisas pelo nome:

// [Link]
export function soma(a, b) { return a + b; }
export function subtrai(a, b) { return a - b; }

// [Link]
import { soma, subtrai } from "./[Link]";

Default Export

Você exporta uma coisa principal:

// [Link]
export default function ola(nome) {
return `Olá, ${nome}!`;
}

// [Link]
import ola from "./[Link]";

[Link](ola("Gabriel"));

---

5. Misturando CommonJS e ES Modules

No [Link] atual, você pode usar os dois sistemas, mas não pode misturar dentro do mesmo arquivo.

Definição no [Link]:

{
"type": "module"
}

Se type: "module" o Node usa import/export.


Se não definir o Node usa require/[Link].

---

6. Avançado: Como o Node carrega módulos (require cache)

O Node tem um mecanismo de cache:

Quando você importa um módulo com require ou import, o Node carrega o arquivo só uma vez.

Nas próximas vezes, ele reutiliza do cache (não executa de novo).

// [Link]
let count = 0;

function incrementar() {
count++;
[Link]("Contador:", count);
}

[Link] = incrementar;
// [Link]
const incrementar = require("./contador");

incrementar(); // Contador: 1
incrementar(); // Contador: 2

const novamente = require("./contador");


novamente(); // Contador: 3 (mesmo cache)

Ou seja: um módulo é singleton no [Link].

---

7. Módulos externos com NPM

Para usar pacotes de terceiros:

npm init -y
npm install lodash

const _ = require("lodash");

[Link](_.capitalize("amigão poderoso!"));

O lodash foi importado de node_modules.

---

8. Boas práticas

Use ES Modules (import/export) em projetos novos, pois é o futuro do JS.


Use CommonJS (require) em projetos antigos ou legados.
Sempre nomeie seus módulos de forma clara ([Link], [Link]).
Separe responsabilidades: cada módulo deve ter uma função clara.
Prefira default export para coisas únicas, e named exports para utilitários.

---

9. Conclusão

require/[Link] CommonJS (antigo, ainda usado).

import/export ES Modules (moderno, padrão oficial).


Node lida com ambos, mas projetos novos devem usar ESM.

Entender como o Node carrega módulos (cache, singletons) é diferencial no mercado.

Modularizar bem = código limpo, escalável e fácil de manter.

---

Amigão, essa foi a super aula 2 sobre módulos no [Link] .


Na próxima vez, já quer que eu prepare alguns exercícios práticos no final (nível fácil, médio e avançado) pra você
treinar depois da leitura?

Perfeito, amigão
Essa vai ser uma super aula 3 sobre o módulo fs (File System) no [Link]. Vamos aprender a criar, ler, atualizar e
deletar arquivos, tanto na forma síncrona quanto assíncrona, com dicas profissionais para você realmente dominar e se
diferenciar no mercado.

---

Super Aula 3: Módulo FS no [Link] – CRUD de Arquivos

---

1. O que é o módulo fs?

O fs (File System) é um módulo interno do [Link] que permite manipular arquivos e diretórios.

Ele tem duas formas principais de uso:

Assíncrona (não bloqueante) recomendada na maioria dos casos.

Síncrona (bloqueante) executa e trava a aplicação até terminar (bom apenas para scripts rápidos).

Como importar:

const fs = require("fs"); // CommonJS


// ou
import fs from "fs"; // ES Modules
---

2. Criar arquivos

Assíncrono ([Link])

[Link]("[Link]", "Olá, mundo!", (err) => {


if (err) throw err;
[Link]("Arquivo criado com sucesso!");
});

Síncrono ([Link])

[Link]("[Link]", "Olá, mundo!");


[Link]("Arquivo criado com sucesso!");

Se o arquivo já existir ele será sobrescrito.

---

3. Ler arquivos

Assíncrono ([Link])

[Link]("[Link]", "utf-8", (err, data) => {


if (err) throw err;
[Link]("Conteúdo:", data);
});

Síncrono ([Link])

const data = [Link]("[Link]", "utf-8");


[Link]("Conteúdo:", data);

Sempre use "utf-8" para evitar receber buffers (dados brutos).

---

4. Atualizar arquivos

Adicionar conteúdo (append)

[Link]("[Link]", "\nNova linha adicionada!", (err) => {


if (err) throw err;
[Link]("Conteúdo adicionado!");
});

Sobrescrever conteúdo

Mesma função de criar ([Link]), pois ela sobrescreve o arquivo inteiro:

[Link]("[Link]", "Novo conteúdo!", (err) => {


if (err) throw err;
[Link]("Arquivo sobrescrito!");
});

---

5. Deletar arquivos

Assíncrono ([Link])

[Link]("[Link]", (err) => {


if (err) throw err;
[Link]("Arquivo deletado!");
});

Síncrono ([Link])

[Link]("[Link]");
[Link]("Arquivo deletado!");

---

6. Criar e manipular diretórios

Criar pasta

[Link]("novaPasta", (err) => {


if (err) throw err;
[Link]("Pasta criada!");
});

Ler pasta

[Link](".", (err, files) => {


if (err) throw err;
[Link]("Arquivos no diretório:", files);
});

Remover pasta

[Link]("novaPasta", (err) => {


if (err) throw err;
[Link]("Pasta removida!");
});

rmdir só remove diretórios vazios.

---

7. Avançado: Usando fs/promises com async/await

O Node tem uma versão promisificada do fs, ideal para código moderno com async/await:

import { writeFile, readFile, appendFile, unlink } from "fs/promises";

async function exemplo() {


try {
await writeFile("[Link]", "Conteúdo inicial!");
[Link]("Arquivo criado!");

const data = await readFile("[Link]", "utf-8");


[Link]("Conteúdo lido:", data);

await appendFile("[Link]", "\nLinha extra!");


[Link]("Linha adicionada!");

await unlink("[Link]");
[Link]("Arquivo deletado!");
} catch (err) {
[Link]("Erro:", err);
}
}

exemplo();

Esse padrão é o mais profissional para sistemas grandes.

---
8. Boas práticas de profissional

Prefira fs/promises + async/await código limpo e moderno.


Sempre trate erros (arquivo pode não existir, sem permissão, etc.).
Nunca use funções síncronas em aplicações de produção podem travar o Event Loop.
Use path para manipular caminhos de forma segura (evitar bugs em Windows/Linux):

const path = require("path");


const filePath = [Link](__dirname, "data", "[Link]");

---

9. Conclusão

fs é o canivete suíço do [Link] para arquivos.

Aprendemos CRUD completo:

Criar writeFile

Ler readFile

Atualizar appendFile / writeFile

Deletar unlink

Manipulação de diretórios: mkdir, readdir, rmdir.

Código moderno fs/promises + async/await.

Seguir boas práticas evita travamentos e bugs em produção.

---

Amigão, essa foi a super aula 3 sobre o módulo fs.


Na próxima vez você quer que eu já monte exercícios práticos (CRUD de arquivos e diretórios) no final, nível fácil,
médio e avançado, igual combinamos?

Boa, amigão
Agora vamos entrar no coração do [Link] na web criar servidores HTTP e HTTPS do zero, usando apenas os
módulos nativos. Vou dividir em duas partes como pediu:
1. Super Aula HTTP

2. Super Aula HTTPS

---

Super Aula 4 – Criando Servidores no [Link]

---

Parte 1 – Servidor HTTP

1 O que é o módulo http?

O http é um módulo interno do [Link].

Permite criar um servidor web sem precisar de frameworks como Express.

Trabalha com dois objetos principais:

req (request) representa a requisição do cliente.

res (response) representa a resposta do servidor.

---

2 Criando o servidor mais simples

const http = require("http");

// Cria o servidor
const server = [Link]((req, res) => {
[Link](200, { "Content-Type": "text/plain" });
[Link]("Olá, mundo! Servidor HTTP rodando ");
});

// Roda na porta 3000


[Link](3000, () => {
[Link]("Servidor HTTP rodando em [Link]
});

Quando você acessar [Link] o navegador mostra a resposta.

---

3 Lidando com rotas básicas

const http = require("http");

const server = [Link]((req, res) => {


if ([Link] === "/" && [Link] === "GET") {
[Link](200, { "Content-Type": "text/html" });
[Link]("<h1>Bem-vindo à Home</h1>");
} else if ([Link] === "/sobre" && [Link] === "GET") {
[Link](200, { "Content-Type": "application/json" });
[Link]([Link]({ mensagem: "Página Sobre" }));
} else {
[Link](404, { "Content-Type": "text/plain" });
[Link]("Página não encontrada");
}
});

[Link](3000, () => {
[Link]("Servidor rodando em [Link]
});

---

4 Trabalhando com query strings

const http = require("http");


const url = require("url");

const server = [Link]((req, res) => {


const parsedUrl = [Link]([Link], true);

if ([Link] === "/saudacao") {


const nome = [Link] || "Visitante";
[Link](200, { "Content-Type": "text/plain" });
[Link](`Olá, ${nome}!`);
} else {
[Link](404);
[Link]("Não encontrado");
}
});

[Link](3000, () => [Link]("[Link]

Acesse: [Link]

---

5 Recebendo dados (POST)

const http = require("http");

const server = [Link]((req, res) => {


if ([Link] === "/enviar" && [Link] === "POST") {
let body = "";

[Link]("data", chunk => {


body += [Link]();
});

[Link]("end", () => {
[Link](200, { "Content-Type": "application/json" });
[Link]([Link]({ recebido: body }));
});
} else {
[Link](404);
[Link]("Rota não encontrada");
}
});

[Link](3000, () => [Link]("[Link]

Agora você pode enviar dados com um fetch ou Postman.

---

Conclusão HTTP

Aprendemos a criar servidor, rotas, query strings e lidar com POST.

Tudo usando apenas o módulo http.


---

Parte 2 – Servidor HTTPS

1 O que é o módulo https?

O https é parecido com o http, mas usa SSL/TLS para criptografar a comunicação.

Requer certificado digital (pode ser real ou autoassinado).

---

2 Criando certificados autoassinados (para testes)

No terminal:

openssl genrsa -out [Link] 2048


openssl req -new -key [Link] -out [Link]
openssl x509 -req -days 365 -in [Link] -signkey [Link] -out [Link]

Isso gera dois arquivos:

[Link] (chave privada)

[Link] (certificado)

---

3 Criando servidor HTTPS

const https = require("https");


const fs = require("fs");

const options = {
key: [Link]("[Link]"),
cert: [Link]("[Link]")
};

const server = [Link](options, (req, res) => {


[Link](200, { "Content-Type": "text/plain" });
[Link]("Servidor HTTPS seguro ");
});

[Link](3443, () => {
[Link]("Servidor HTTPS rodando em [Link]
});

Agora você acessa [Link]


(O navegador vai avisar que o certificado é inválido, mas é só porque é autoassinado).

---

4 Combinando HTTP e HTTPS

Você pode rodar dois servidores ao mesmo tempo:

const http = require("http");


const https = require("https");
const fs = require("fs");

const options = {
key: [Link]("[Link]"),
cert: [Link]("[Link]")
};

const handler = (req, res) => {


[Link](200, { "Content-Type": "text/plain" });
[Link]("Servidor rodando tanto em HTTP quanto em HTTPS");
};

[Link](handler).listen(3000, () => {
[Link]("HTTP -> [Link]
});

[Link](options, handler).listen(3443, () => {


[Link]("HTTPS -> [Link]
});

---

Conclusão HTTPS

https é quase idêntico ao http, mas exige certificado.


Permite segurança, encriptação e é obrigatório para sistemas profissionais.

No mercado de trabalho, sempre use HTTPS em produção.

---

Amigão, essa foi a super aula 4, com HTTP e HTTPS no [Link] .


Na próxima, quer que a gente siga pro módulo path (manipulação de caminhos de arquivos) ou já mergulhamos em
algo mais prático tipo construir uma API REST sem frameworks?

Show de bola, amigão


Sim, exatamente — dentro do nosso calendário de [Link], depois de aprender http e https, o próximo passo natural é
criar um mini-servidor robusto que retorna JSON. Isso é a base para construir APIs REST profissionais.

Bora caprichar

---

Super Aula 5 – Mini-servidor robusto retornando JSON

---

1 O que significa “robusto” aqui?

Não é só um hello world. Nosso servidor precisa:

Retornar JSON válido.

Ter rotas diferentes.

Tratar erros e rotas inexistentes.

Seguir boas práticas de API (headers, status codes).

---

2 Estrutura básica de um servidor JSON

const http = require("http");


const server = [Link]((req, res) => {
[Link](200, { "Content-Type": "application/json" });
[Link]([Link]({ mensagem: "Servidor JSON rodando " }));
});

[Link](3000, () => {
[Link]("Servidor rodando em [Link]
});

Se você acessar no navegador verá o JSON.

---

3 Criando rotas (endpoints)

Vamos adicionar algumas rotas para simular uma API:

const http = require("http");

const server = [Link]((req, res) => {


[Link]("Content-Type", "application/json");

if ([Link] === "/" && [Link] === "GET") {


[Link](200);
[Link]([Link]({ mensagem: "Bem-vindo à API " }));

} else if ([Link] === "/usuarios" && [Link] === "GET") {


const usuarios = [
{ id: 1, nome: "Gabriel" },
{ id: 2, nome: "Pedro" },
{ id: 3, nome: "Aurélio" },
];
[Link](200);
[Link]([Link](usuarios));

} else {
[Link](404);
[Link]([Link]({ erro: "Rota não encontrada" }));
}
});

[Link](3000, () => {
[Link]("Servidor rodando em [Link]
});
Agora você pode acessar:

[Link] mensagem de boas-vindas.

[Link] lista de usuários em JSON.

Qualquer outra rota erro 404 em JSON.

---

4 Recebendo dados via POST

Um servidor robusto precisa aceitar dados do cliente.

const http = require("http");

let usuarios = [{ id: 1, nome: "Gabriel" }];

const server = [Link]((req, res) => {


[Link]("Content-Type", "application/json");

if ([Link] === "/usuarios" && [Link] === "GET") {


[Link](200);
[Link]([Link](usuarios));

} else if ([Link] === "/usuarios" && [Link] === "POST") {


let body = "";

[Link]("data", chunk => {


body += [Link]();
});

[Link]("end", () => {
try {
const novoUsuario = [Link](body);
[Link] = [Link] + 1;
[Link](novoUsuario);

[Link](201);
[Link]([Link](novoUsuario));
} catch (err) {
[Link](400);
[Link]([Link]({ erro: "JSON inválido" }));
}
});

} else {
[Link](404);
[Link]([Link]({ erro: "Rota não encontrada" }));
}
});

[Link](3000, () => {
[Link]("Servidor rodando em [Link]
});

Agora você pode:

GET [Link] lista de usuários.

POST [Link] com body JSON:

{
"nome": "João"
}

Ele será adicionado à lista.

---

5 Boas práticas para robustez

Sempre defina o Content-Type como application/json.


Sempre retorne status codes corretos (200, 201, 400, 404, 500).
Use try/catch ao trabalhar com [Link].
Nunca deixe o servidor quebrar por erro não tratado.

---

6 Próximo passo

Esse mini-servidor é robusto o suficiente para testes e estudos.


No mercado de trabalho, o próximo nível é usar frameworks como Express, mas saber fazer na unha (sem
frameworks) te dá um diferencial gigante.

---
Amigão, essa foi a super aula 5: construímos um mini-servidor robusto que retorna JSON, com rotas, tratamento de
erros e suporte a POST.

Quer que eu faça já na próxima aula um CRUD completo (Create, Read, Update, Delete) em JSON sem usar banco de
dados (só em memória), ou prefere primeiro uma aula sobre o módulo path antes de avançarmos para CRUD?

Show de bola, amigão


Sim, exatamente — dentro do nosso calendário de [Link], depois de aprender http e https, o próximo passo natural é
criar um mini-servidor robusto que retorna JSON. Isso é a base para construir APIs REST profissionais.

Bora caprichar

---

Super Aula 5 – Mini-servidor robusto retornando JSON

---

1 O que significa “robusto” aqui?

Não é só um hello world. Nosso servidor precisa:

Retornar JSON válido.

Ter rotas diferentes.

Tratar erros e rotas inexistentes.

Seguir boas práticas de API (headers, status codes).

---

2 Estrutura básica de um servidor JSON

const http = require("http");

const server = [Link]((req, res) => {


[Link](200, { "Content-Type": "application/json" });
[Link]([Link]({ mensagem: "Servidor JSON rodando " }));
});
[Link](3000, () => {
[Link]("Servidor rodando em [Link]
});

Se você acessar no navegador verá o JSON.

---

3 Criando rotas (endpoints)

Vamos adicionar algumas rotas para simular uma API:

const http = require("http");

const server = [Link]((req, res) => {


[Link]("Content-Type", "application/json");

if ([Link] === "/" && [Link] === "GET") {


[Link](200);
[Link]([Link]({ mensagem: "Bem-vindo à API " }));

} else if ([Link] === "/usuarios" && [Link] === "GET") {


const usuarios = [
{ id: 1, nome: "Gabriel" },
{ id: 2, nome: "Pedro" },
{ id: 3, nome: "Aurélio" },
];
[Link](200);
[Link]([Link](usuarios));

} else {
[Link](404);
[Link]([Link]({ erro: "Rota não encontrada" }));
}
});

[Link](3000, () => {
[Link]("Servidor rodando em [Link]
});

Agora você pode acessar:

[Link] mensagem de boas-vindas.

[Link] lista de usuários em JSON.


Qualquer outra rota erro 404 em JSON.

---

4 Recebendo dados via POST

Um servidor robusto precisa aceitar dados do cliente.

const http = require("http");

let usuarios = [{ id: 1, nome: "Gabriel" }];

const server = [Link]((req, res) => {


[Link]("Content-Type", "application/json");

if ([Link] === "/usuarios" && [Link] === "GET") {


[Link](200);
[Link]([Link](usuarios));

} else if ([Link] === "/usuarios" && [Link] === "POST") {


let body = "";

[Link]("data", chunk => {


body += [Link]();
});

[Link]("end", () => {
try {
const novoUsuario = [Link](body);
[Link] = [Link] + 1;
[Link](novoUsuario);

[Link](201);
[Link]([Link](novoUsuario));
} catch (err) {
[Link](400);
[Link]([Link]({ erro: "JSON inválido" }));
}
});

} else {
[Link](404);
[Link]([Link]({ erro: "Rota não encontrada" }));
}
});

[Link](3000, () => {
[Link]("Servidor rodando em [Link]
});

Agora você pode:

GET [Link] lista de usuários.

POST [Link] com body JSON:

{
"nome": "João"
}

Ele será adicionado à lista.

---

5 Boas práticas para robustez

Sempre defina o Content-Type como application/json.


Sempre retorne status codes corretos (200, 201, 400, 404, 500).
Use try/catch ao trabalhar com [Link].
Nunca deixe o servidor quebrar por erro não tratado.

---

6 Próximo passo

Esse mini-servidor é robusto o suficiente para testes e estudos.


No mercado de trabalho, o próximo nível é usar frameworks como Express, mas saber fazer na unha (sem
frameworks) te dá um diferencial gigante.

---

Amigão, essa foi a super aula 5: construímos um mini-servidor robusto que retorna JSON, com rotas, tratamento de
erros e suporte a POST.

Quer que eu faça já na próxima aula um CRUD completo (Create, Read, Update, Delete) em JSON sem usar banco de
dados (só em memória), ou prefere primeiro uma aula sobre o módulo path antes de avançarmos para CRUD?

Boa, amigão! Parabéns pela primeira semana fechada com chave de ouro e bora com tudo pra segunda semana:
EXPRESS — o coração do Node backend.

Você já instalou e importou, então estamos prontos. Hoje vamos fazer a Super Aula 6: Rotas básicas, GET e POST em
Express.

---

Super Aula 6 – Express: Rotas Básicas (GET e POST)

---

1 O que é o Express?

O Express é um framework minimalista para [Link] que simplifica a criação de servidores.


Com ele, você escreve muito menos código que no http puro e ganha organização.

---

2 Estrutura inicial de um projeto Express

// [Link]
const express = require("express");
const app = express();
const PORT = 3000;

// Middleware para interpretar JSON no body


[Link]([Link]());

// Servidor
[Link](PORT, () => {
[Link](` Servidor rodando em [Link]
});

Agora você já tem um servidor Express rodando.

---

3 Criando Rotas GET


Rotas GET são usadas para buscar dados.

// Rota inicial
[Link]("/", (req, res) => {
[Link]("Bem-vindo à API com Express ");
});

// Rota de usuários
[Link]("/usuarios", (req, res) => {
const usuarios = [
{ id: 1, nome: "Gabriel" },
{ id: 2, nome: "Pedro" },
{ id: 3, nome: "Aurélio" },
];
[Link](usuarios);
});

Acesse no navegador:

[Link]

[Link]

---

4 Criando Rotas POST

Rotas POST servem para enviar dados ao servidor.

let usuarios = [{ id: 1, nome: "Gabriel" }];

[Link]("/usuarios", (req, res) => {


const novoUsuario = [Link]; // pega os dados enviados no body
[Link] = [Link] + 1;
[Link](novoUsuario);

[Link](201).json(novoUsuario);
});

Como testar:

Use o Postman, Insomnia ou até fetch no navegador.

Envie um POST para [Link] com JSON no body:


{
"nome": "João"
}

O servidor retorna o novo usuário já com id.

---

5 Resumindo

[Link]() buscar dados.


[Link]() enviar dados.
[Link]() resposta simples (texto/HTML).
[Link]() resposta JSON.
[Link](201).json() resposta com código de status.

---

6 Próximo Passo

Depois de aprender rotas básicas, você pode evoluir para:

Rotas com parâmetros (/usuarios/:id).

Rotas com query strings (/produtos?categoria=notebooks).

Organização com Router (para dividir as rotas em arquivos separados).

---

Amigão, quer que eu já prepare a aula de amanhã sobre rotas dinâmicas com parâmetros e query strings no Express?
Isso vai te deixar bem mais perto de ser um profissional diferenciado.

Boa, amigão
Hoje vamos detonar numa das partes mais importantes do Express: os middlewares.
Eles são o que fazem o Express ser poderoso e flexível. Bora pra Super Aula 7

---
Super Aula 7 – Middlewares no Express (globais e locais)

---

1 O que é um Middleware?

Middleware é uma função que fica no meio da requisição e da resposta.

Ou seja:

1. O cliente faz uma requisição (req).

2. O middleware processa, valida ou altera essa requisição.

3. Depois, passa para a próxima etapa com next().

4. Por fim, a rota responde (res).

Estrutura básica:

function meuMiddleware(req, res, next) {


[Link]("Middleware executado!");
next(); // passa para o próximo middleware ou rota
}

---

2 Middleware Global

Middleware global é aplicado a todas as rotas.

Exemplo: logar cada requisição:

const express = require("express");


const app = express();
const PORT = 3000;

[Link]([Link]()); // middleware nativo para JSON


// Middleware global (log de requisições)
[Link]((req, res, next) => {
[Link](`${[Link]} - ${[Link]}`);
next(); // sem isso trava
});

[Link]("/", (req, res) => {


[Link]("Bem-vindo à API ");
});

[Link](PORT, () => [Link](`Servidor rodando em [Link]

Agora qualquer rota chamada passa primeiro pelo middleware.

---

3 Middleware Local

Middleware local é aplicado apenas em rotas específicas.

Exemplo: checar autenticação numa rota:

function verificarToken(req, res, next) {


if ([Link]["token"] === "123") {
next(); // autorizado
} else {
[Link](403).json({ erro: "Acesso negado" });
}
}

// Rota protegida com middleware local


[Link]("/dashboard", verificarToken, (req, res) => {
[Link]({ mensagem: "Bem-vindo ao painel secreto " });
});

Agora:

GET /dashboard com header token=123 funciona.

Sem esse header retorna 403.

---
4 Vários Middlewares em uma rota

Você pode encadear middlewares:

function primeiro(req, res, next) {


[Link]("Primeiro middleware");
next();
}

function segundo(req, res, next) {


[Link]("Segundo middleware");
next();
}

[Link]("/teste", primeiro, segundo, (req, res) => {


[Link]("Finalizado ");
});

Ordem importa executa na sequência declarada.

---

5 Exemplos práticos de Middlewares

Autenticação validar login/token.

Logs registrar acessos.

Tratamento de erros capturar erros centralmente.

CORS liberar acesso entre domínios.

Upload de arquivos (com multer).

---

6 Middleware de Erro (especial)

Um middleware de erro tem 4 parâmetros: (err, req, res, next).

Exemplo:

[Link]((err, req, res, next) => {


[Link]("Erro:", [Link]);
[Link](500).json({ erro: "Erro interno no servidor" });
});

---

Dúvida extra: Módulo Global vs Local

Isso não é sobre middleware, mas sobre como instalamos pacotes NPM.

Instalação Local

npm install express

Instala na pasta do projeto (node_modules).

Usado apenas por aquele projeto.

Correto para dependências do projeto.

No [Link] aparece em "dependencies".

---

Instalação Global

npm install -g nodemon

Instala na máquina toda.

Usado como ferramenta em qualquer pasta.

Exemplo: nodemon, pm2, typescript.

Não aparece em [Link] porque não é do projeto, é da máquina.

---

Resumindo

Middleware = função que processa req/res antes da rota.


Globais aplicam em todas as rotas ([Link]).

Locais aplicam em rotas específicas.

Módulos locais instalados por projeto.

Módulos globais instalados na máquina inteira.

---

Amigão, na próxima aula você quer que eu prepare sobre rotas dinâmicas no Express (com parâmetros e query
strings), ou prefere que a gente já avance para tratamento de erros com middlewares (bem profissional)?

Boa, amigão
Então hoje é Super Aula 8: vamos mergulhar nos parâmetros no Express Query Parameter, Route Parameter e Body
Parameter.
Isso é a base para construir APIs profissionais de verdade.

---

Super Aula 8 – Query, Route e Body Parameters no Express

---

1 Relembrando: o que são parâmetros?

Parâmetros são maneiras diferentes de passar dados para a API.


Temos três principais:

1. Query Parameters enviados na URL após ?.

2. Route Parameters parte da rota (dinâmico).

3. Body Parameters enviados no corpo da requisição (JSON).

---
2 Query Parameters ([Link])

Usados para filtrar ou buscar dados.


Formato:

/usuarios?idade=20&cidade=Luanda

Exemplo no Express:

[Link]("/usuarios", (req, res) => {


const { idade, cidade } = [Link];
[Link]({ mensagem: `Filtrando usuários com idade=${idade} e cidade=${cidade}` });
});

Se acessar:

[Link]

Retorna:

{
"mensagem": "Filtrando usuários com idade=20 e cidade=Luanda"
}

---

3 Route Parameters ([Link])

Usados quando você quer identificar um recurso específico.


Formato:

/usuarios/10

Exemplo no Express:

[Link]("/usuarios/:id", (req, res) => {


const { id } = [Link];
[Link]({ mensagem: `Buscando usuário com id=${id}` });
});

Se acessar:

[Link]
Retorna:

{
"mensagem": "Buscando usuário com id=10"
}

Dica: você pode ter mais de um parâmetro:

[Link]("/produtos/:categoria/:id", (req, res) => {


const { categoria, id } = [Link];
[Link]({ categoria, id });
});

URL:

/produtos/notebooks/5

Retorna:

{
"categoria": "notebooks",
"id": "5"
}

---

4 Body Parameters ([Link])

Usados para criar ou atualizar dados.


Formato: JSON no corpo da requisição.

Exemplo no Express:

[Link]([Link]()); // necessário para interpretar JSON

[Link]("/usuarios", (req, res) => {


const { nome, idade } = [Link];
[Link](201).json({ mensagem: `Usuário ${nome} com idade ${idade} criado!` });
});

Enviar no Postman/Insomnia:

{
"nome": "Gabriel",
"idade": 25
}

Resposta:

{
"mensagem": "Usuário Gabriel com idade 25 criado!"
}

---

5 Diferença entre eles

TipoOnde aparece?Quando usar?

Query ([Link])Depois de ? na URLFiltros, paginação, buscas opcionais


Route ([Link])Dentro da rota com :paramIdentificar recursos específicos (ex: /usuarios/1)
Body ([Link])Corpo da requisição (JSON)Criar/atualizar dados

---

6 Exemplo Completo

const express = require("express");


const app = express();
[Link]([Link]());

// Query
[Link]("/produtos", (req, res) => {
const { categoria } = [Link];
[Link]({ mensagem: `Filtrando produtos da categoria: ${categoria}` });
});

// Route
[Link]("/produtos/:id", (req, res) => {
const { id } = [Link];
[Link]({ mensagem: `Buscando produto com id=${id}` });
});

// Body
[Link]("/produtos", (req, res) => {
const { nome, preco } = [Link];
[Link](201).json({ mensagem: `Produto ${nome} criado com preço ${preco}` });
});
[Link](3000, () => [Link](" Servidor rodando em [Link]

---

Resumindo

Query Params ([Link]) usados para filtrar.

Route Params ([Link]) usados para identificar.

Body Params ([Link]) usados para enviar dados.

---

Amigão, na próxima aula você quer que eu prepare sobre CRUD completo em Express (Create, Read, Update,
Delete) ou prefere que a gente faça uma aula só de tratamento de erros profissional com middlewares antes de
avançar?

Boa, amigão! Você tá voando. Agora entramos na parte profissional de verdade: Arquitetura MVC no Express.
É aqui que você começa a se diferenciar no mercado, porque não vai mais escrever código bagunçado, mas sim
organizado como nas empresas.

Bora pra Super Aula 9 – Estrutura MVC no Express

---

Super Aula 9 – Estrutura MVC no Express

---

1 O que é MVC?

MVC é uma arquitetura de software que organiza o projeto em três camadas:

M Model (Modelo)
Onde ficam as regras de negócio e dados (ex.: produtos, usuários).

V View (Visão)
Onde renderiza a saída. Em APIs REST, normalmente não usamos views HTML, mas sim respostas JSON.
C Controller (Controlador)
Onde ficam as funções que recebem a requisição e decidem o que fazer (chamam os models e retornam resposta).

Resumindo:

Model = dados.

Controller = lógica.

View = resposta.

---

2 Estrutura de Pastas

Um projeto Express em MVC pode ser organizado assim:

meu-projeto/
[Link] # Arquivo principal
routes/ # Rotas da aplicação
[Link]
controllers/ # Lógica das rotas
[Link]
models/ # Modelos de dados
[Link]
data/ # Dados simulados (ou banco futuramente)
[Link]

---

3 Criando cada parte (Exemplo: Produtos)

1. Model (models/[Link])

// Simulando um "banco de dados" em memória


let produtos = [
{ id: 1, nome: "Notebook Dell", preco: 4500 },
{ id: 2, nome: "Mouse Gamer", preco: 150 },
];

function listarProdutos() {
return produtos;
}

function buscarProdutoPorId(id) {
return [Link](p => [Link] === id);
}

function criarProduto(novoProduto) {
[Link] = [Link] + 1;
[Link](novoProduto);
return novoProduto;
}

[Link] = { listarProdutos, buscarProdutoPorId, criarProduto };

---

2. Controller (controllers/[Link])

const Produto = require("../models/produtoModel");

function getProdutos(req, res) {


const lista = [Link]();
[Link](lista);
}

function getProdutoPorId(req, res) {


const { id } = [Link];
const produto = [Link](Number(id));

if (!produto) {
return [Link](404).json({ erro: "Produto não encontrado" });
}
[Link](produto);
}

function postProduto(req, res) {


const { nome, preco } = [Link];
if (!nome || !preco) {
return [Link](400).json({ erro: "Nome e preço são obrigatórios" });
}

const novoProduto = [Link]({ nome, preco });


[Link](201).json(novoProduto);
}
[Link] = { getProdutos, getProdutoPorId, postProduto };

---

3. Routes (routes/[Link])

const express = require("express");


const router = [Link]();
const produtoController = require("../controllers/produtoController");

[Link]("/", [Link]);
[Link]("/:id", [Link]);
[Link]("/", [Link]);

[Link] = router;

---

4. Arquivo Principal ([Link])

const express = require("express");


const app = express();
const PORT = 3000;

[Link]([Link]());

// Importa as rotas
const produtoRoutes = require("./routes/produtoRoutes");

// Usa as rotas de produtos


[Link]("/produtos", produtoRoutes);

// Rota inicial
[Link]("/", (req, res) => {
[Link]("API com MVC rodando ");
});

[Link](PORT, () => {
[Link](`Servidor rodando em [Link]
});

---
4 Testando

GET /produtos lista todos.

GET /produtos/1 busca produto por ID.

POST /produtos adiciona produto:

{
"nome": "Teclado Mecânico",
"preco": 300
}

---

5 Vantagens do MVC

Código mais organizado e limpo.


Cada parte tem sua responsabilidade fácil de manter.
Mais próximo do que empresas realmente usam.
Escalável: fácil adicionar novas entidades (ex.: usuários, pedidos).

---

Resumindo

Model cuida dos dados.

Controller cuida da lógica.

Routes define os caminhos e chama os controllers.

[Link] conecta tudo.

---

Amigão, na próxima aula você prefere que eu prepare uma super aula sobre CRUD completo (Create, Read, Update,
Delete) dentro da estrutura MVC, ou já partimos para conexão com banco de dados (SQLite ou MongoDB) para
deixar o projeto mais real?

Boa, amigão! Agora sim você tá entrando em terreno de profissional de backend:


CRUD de Usuários + Upload de Arquivos (imagem de perfil).
Essa é uma Super Aula 10

---

Super Aula 10 – CRUD de Usuários + Upload de Arquivos no Express

---

1 O que vamos construir?

Um CRUD de usuários.

Cada usuário tem:

id

nome

email

senha (simples por enquanto, sem criptografia)

imagem (upload da foto do perfil).

Vamos salvar os usuários em um arquivo JSON.

As imagens vão para uma pasta uploads/.

---

2 Estrutura do Projeto

meu-projeto/
[Link]
routes/
[Link]
controllers/
[Link]
models/
[Link]
data/
[Link]
uploads/ # onde vão as imagens enviadas

---

3 Configurando Upload com multer

multer é o middleware de upload para o Express.

Instalação:

npm install multer

---

4 Model (models/[Link])

const fs = require("fs");
const path = require("path");

const filePath = [Link](__dirname, "../data/[Link]");

// Carrega usuários
function carregarUsuarios() {
if (![Link](filePath)) return [];
const data = [Link](filePath);
return [Link](data);
}

// Salva usuários
function salvarUsuarios(usuarios) {
[Link](filePath, [Link](usuarios, null, 2));
}

// CRUD
function listarUsuarios() {
return carregarUsuarios();
}

function buscarPorId(id) {
const usuarios = carregarUsuarios();
return [Link](u => [Link] === id);
}
function criarUsuario(novoUsuario) {
const usuarios = carregarUsuarios();
[Link] = [Link] + 1;
[Link](novoUsuario);
salvarUsuarios(usuarios);
return novoUsuario;
}

[Link] = { listarUsuarios, buscarPorId, criarUsuario };

---

5 Controller (controllers/[Link])

const Usuario = require("../models/usuarioModel");

function getUsuarios(req, res) {


[Link]([Link]());
}

function getUsuarioPorId(req, res) {


const { id } = [Link];
const usuario = [Link](Number(id));

if (!usuario) {
return [Link](404).json({ erro: "Usuário não encontrado" });
}
[Link](usuario);
}

function postUsuario(req, res) {


const { nome, email, senha } = [Link];
const imagem = [Link] ? [Link] : null;

if (!nome || !email || !senha) {


return [Link](400).json({ erro: "Nome, email e senha são obrigatórios" });
}

const novoUsuario = [Link]({ nome, email, senha, imagem });


[Link](201).json(novoUsuario);
}

[Link] = { getUsuarios, getUsuarioPorId, postUsuario };


---

6 Routes (routes/[Link])

const express = require("express");


const router = [Link]();
const usuarioController = require("../controllers/usuarioController");
const multer = require("multer");

// Configuração do multer
const storage = [Link]({
destination: (req, file, cb) => {
cb(null, "uploads/");
},
filename: (req, file, cb) => {
cb(null, [Link]() + "-" + [Link]);
}
});
const upload = multer({ storage });

// Rotas
[Link]("/", [Link]);
[Link]("/:id", [Link]);
[Link]("/", [Link]("imagem"), [Link]);

[Link] = router;

---

7 Arquivo Principal ([Link])

const express = require("express");


const app = express();
const PORT = 3000;

[Link]([Link]());

// Servir arquivos estáticos (imagens)


[Link]("/uploads", [Link]("uploads"));

// Rotas
const usuarioRoutes = require("./routes/usuarioRoutes");
[Link]("/usuarios", usuarioRoutes);
[Link](PORT, () => {
[Link](`Servidor rodando em [Link]
});

---

8 Testando

Criar usuário (POST /usuarios) com form-data

Campos: nome, email, senha

Upload de imagem: imagem (tipo file)

Resposta:

{
"id": 1,
"nome": "Gabriel",
"email": "gabriel@[Link]",
"senha": "123456",
"imagem": "[Link]"
}

Buscar todos

GET /usuarios

Buscar por ID

GET /usuarios/1

---

9 Observações Importantes

As senhas estão salvas em texto plano (isso é só para treino).

Em sistemas reais sempre criptografar a senha (ex.: bcrypt).

O upload aqui é básico depois podemos validar tipo de arquivo e tamanho.


---

Resumindo

Aprendemos a criar CRUD de usuários.

Aprendemos upload de arquivos com multer.

Já podemos servir as imagens no navegador.

---

Amigão, quer que a próxima aula (a última da semana) seja um projeto integrando usuários + produtos, ou prefere
que façamos uma revisão com exercícios práticos antes de partir para outra semana?

Fechamos Semana 2 com chave de ouro, amigão! Agora bora entrar na Semana 3 – Bancos de Dados com [Link],
que é um salto gigante no nível profissional.

---

Super Aula 11 – Introdução a Bancos de Dados SQL vs NoSQL + Conexão com MongoDB (Mongoose)

---

1 O que é Banco de Dados?

Banco de dados é onde armazenamos, organizamos e recuperamos informações.


Sem banco, nossos dados só vivem na memória ou em arquivos locais, que não escalam.

---

2 SQL vs NoSQL

Banco de Dados SQL

SQL = Structured Query Language (linguagem estruturada de consulta).

Ex.: MySQL, PostgreSQL, MariaDB, SQLite.

Estrutura relacional: tabelas linhas e colunas.


Ideal quando os dados têm relacionamentos fortes (ex.: sistema bancário, ERP, e-commerce).

Exemplo em SQL:

CREATE TABLE usuarios (


id INT PRIMARY KEY AUTO_INCREMENT,
nome VARCHAR(100),
email VARCHAR(100) UNIQUE,
senha VARCHAR(100)
);

---

Banco de Dados NoSQL

NoSQL = Not Only SQL.

Estrutura mais flexível, baseada em documentos, chaves-valor, grafos, etc.

Ex.: MongoDB, Redis, Cassandra, CouchDB.

Ideal quando os dados mudam muito ou têm estruturas dinâmicas.

Usa documentos JSON-like.

Exemplo em MongoDB:

{
"nome": "Gabriel",
"email": "gabriel@[Link]",
"senha": "123456",
"imagem": "[Link]"
}

---

3 Comparação Rápida

CaracterísticaSQL (Relacional)NoSQL (Documentos)

EstruturaTabelas fixasFlexível (JSON)


EscalabilidadeVerticalHorizontal
Schemas rígidosSimNão
Velocidade em joinsAltaMais difícil
ExemplosMySQL, PostgresMongoDB, Redis

---

4 [Link] + MongoDB com Mongoose

Para a aula prática, vamos usar MongoDB (NoSQL) porque ele é super usado no mundo real com Node.
O Mongoose é a biblioteca que conecta Node ao MongoDB e ajuda a definir schemas e models.

---

Instalação

npm install mongoose

Se você não tiver MongoDB local, pode usar MongoDB Atlas (cloud gratuito).

---

Conexão (em [Link])

const express = require("express");


const mongoose = require("mongoose");

const app = express();


[Link]([Link]());

// Conectar ao MongoDB
[Link]("mongodb://[Link]:27017/meuBanco", {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => [Link]("Conectado ao MongoDB "))
.catch(err => [Link]("Erro ao conectar:", err));

---

Criando um Model com Mongoose


Exemplo de Usuário.

const { Schema, model } = require("mongoose");

const usuarioSchema = new Schema({


nome: { type: String, required: true },
email: { type: String, required: true, unique: true },
senha: { type: String, required: true },
imagem: { type: String }
}, { timestamps: true });

const Usuario = model("Usuario", usuarioSchema);

[Link] = Usuario;

---

Controller de Usuários (CRUD)

const Usuario = require("../models/usuarioModel");

async function criarUsuario(req, res) {


try {
const { nome, email, senha } = [Link];
const novoUsuario = await [Link]({ nome, email, senha });
[Link](201).json(novoUsuario);
} catch (error) {
[Link](400).json({ erro: [Link] });
}
}

async function listarUsuarios(req, res) {


const usuarios = await [Link]();
[Link](usuarios);
}

async function buscarUsuario(req, res) {


const { id } = [Link];
const usuario = await [Link](id);
if (!usuario) return [Link](404).json({ erro: "Usuário não encontrado" });
[Link](usuario);
}

[Link] = { criarUsuario, listarUsuarios, buscarUsuario };


---

Rotas de Usuário

const express = require("express");


const router = [Link]();
const usuarioController = require("../controllers/usuarioController");

[Link]("/", [Link]);
[Link]("/", [Link]);
[Link]("/:id", [Link]);

[Link] = router;

E no [Link]:

const usuarioRoutes = require("./routes/usuarioRoutes");


[Link]("/usuarios", usuarioRoutes);

---

5 Testando

POST /usuarios cria um novo usuário.

GET /usuarios lista todos.

GET /usuarios/:id busca pelo ID.

---

6 Resumindo

SQL tabelas e relacionamentos.


NoSQL documentos flexíveis.
MongoDB + Mongoose perfeito para APIs modernas com Node.
Já conseguimos salvar, listar e buscar usuários em um banco real.

---
Amigão, para a próxima aula você prefere que eu prepare:

1. Uma super aula de CRUD completo com Mongoose (Create, Read, Update, Delete),
ou 2. Uma introdução rápida a SQL (MySQL/Postgres) com Node, antes de aprofundar no Mongo?

Show, amigão! Então bora pra Super Aula 12 – CRUD completo com Mongoose.
Aqui você vai aprender a manipular dados de verdade no MongoDB (Create, Read, Update e Delete), igualzinho o que
se faz em sistemas profissionais.

---

Super Aula 12 – CRUD Completo com Mongoose

---

1 Estrutura do Projeto

meu-projeto/
[Link]
routes/
[Link]
controllers/
[Link]
models/
[Link]

---

2 Conectando ao MongoDB ([Link])

const express = require("express");


const mongoose = require("mongoose");
const app = express();
const PORT = 3000;

[Link]([Link]());

// Conexão com o MongoDB (local)


[Link]("mongodb://[Link]:27017/cursoNode", {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => [Link]("Conectado ao MongoDB "))
.catch(err => [Link]("Erro ao conectar:", err));

// Rotas
const usuarioRoutes = require("./routes/usuarioRoutes");
[Link]("/usuarios", usuarioRoutes);

[Link](PORT, () => {
[Link](`Servidor rodando em [Link]
});

---

3 Model do Usuário (models/[Link])

const { Schema, model } = require("mongoose");

const usuarioSchema = new Schema({


nome: { type: String, required: true },
email: { type: String, required: true, unique: true },
senha: { type: String, required: true },
imagem: { type: String }
}, { timestamps: true });

const Usuario = model("Usuario", usuarioSchema);

[Link] = Usuario;

---

4 Controller (controllers/[Link])

const Usuario = require("../models/usuarioModel");

// CREATE
async function criarUsuario(req, res) {
try {
const { nome, email, senha, imagem } = [Link];
const novoUsuario = await [Link]({ nome, email, senha, imagem });
[Link](201).json(novoUsuario);
} catch (error) {
[Link](400).json({ erro: [Link] });
}
}

// READ (listar todos)


async function listarUsuarios(req, res) {
try {
const usuarios = await [Link]();
[Link](usuarios);
} catch (error) {
[Link](500).json({ erro: [Link] });
}
}

// READ (buscar por ID)


async function buscarUsuario(req, res) {
try {
const { id } = [Link];
const usuario = await [Link](id);
if (!usuario) return [Link](404).json({ erro: "Usuário não encontrado" });
[Link](usuario);
} catch (error) {
[Link](500).json({ erro: [Link] });
}
}

// UPDATE
async function atualizarUsuario(req, res) {
try {
const { id } = [Link];
const { nome, email, senha, imagem } = [Link];

const usuarioAtualizado = await [Link](


id,
{ nome, email, senha, imagem },
{ new: true, runValidators: true }
);

if (!usuarioAtualizado) return [Link](404).json({ erro: "Usuário não encontrado" });

[Link](usuarioAtualizado);
} catch (error) {
[Link](400).json({ erro: [Link] });
}
}

// DELETE
async function deletarUsuario(req, res) {
try {
const { id } = [Link];
const usuarioDeletado = await [Link](id);

if (!usuarioDeletado) return [Link](404).json({ erro: "Usuário não encontrado" });

[Link]({ mensagem: "Usuário deletado com sucesso " });


} catch (error) {
[Link](500).json({ erro: [Link] });
}
}

[Link] = { criarUsuario, listarUsuarios, buscarUsuario, atualizarUsuario, deletarUsuario };

---

5 Rotas (routes/[Link])

const express = require("express");


const router = [Link]();
const usuarioController = require("../controllers/usuarioController");

[Link]("/", [Link]); // Create


[Link]("/", [Link]); // Read all
[Link]("/:id", [Link]); // Read one
[Link]("/:id", [Link]); // Update
[Link]("/:id", [Link]);// Delete

[Link] = router;

---

6 Testando no Insomnia/Postman

1. Criar usuário POST /usuarios

{
"nome": "Gabriel",
"email": "gabriel@[Link]",
"senha": "123456",
"imagem": "[Link]"
}
2. Listar todos GET /usuarios

3. Buscar por ID GET /usuarios/ID_DO_USUARIO

4. Atualizar PUT /usuarios/ID_DO_USUARIO

{
"nome": "Gabriel Pedro",
"email": "gabriel@[Link]",
"senha": "novaSenha"
}

5. Deletar DELETE /usuarios/ID_DO_USUARIO

---

7 O que aprendemos hoje

Criar, ler, atualizar e deletar documentos no MongoDB.


Estrutura básica de um CRUD profissional no Express.
Como lidar com erros no banco.

---

Amigão, fechamos o CRUD completo no MongoDB.


Agora te pergunto: quer que a próxima aula (Super Aula 13) seja a introdução a SQL (MySQL/Postgres) com [Link],
ou prefere que eu prepare antes um CRUD com upload de imagem no Mongo usando GridFS/Multer para deixar o
projeto mais real?

Boa, irmão! Agora entramos num módulo crucial para ser profissional de backend: Segurança e Autenticação.
Hoje vamos falar sobre o conceito de autenticação e como usar hashing com bcrypt para proteger senhas.

---

Super Aula 13 – Introdução à Autenticação e Hashing com Bcrypt

---
1 O que é Autenticação?

Autenticação é o processo de verificar a identidade de um usuário.


Exemplo: quando você faz login no Facebook ou Gmail, o sistema confirma se o email e a senha realmente pertencem
a você.

Diferença importante:

Autenticação confirmar quem você é (login).

Autorização confirmar o que você pode fazer (permissões, papéis).

---

2 Por que não guardar senhas em texto puro?

ERRADO:

{ "email": "user@[Link]", "senha": "123456" }

Se o banco vaza, acabou: todas as senhas dos usuários estão expostas.

CERTO: usamos hashing.

---

3 O que é Hashing?

Hashing é um processo irreversível que transforma a senha em uma sequência única de caracteres.
Exemplo com bcrypt:

Senha original: 123456


Hash gerado: $2b$10$N9qo8uLOickgx2ZMRZo5i.ejQyEvsJrXw0h8Tb4xQf5Tf3e7.ZzW2

Importante: você nunca consegue “voltar” da hash para a senha original.


Para validar, o bcrypt compara a senha digitada com o hash armazenado.

---

4 Instalando o bcrypt
npm install bcrypt

---

5 Exemplo Simples de Hashing

const bcrypt = require("bcrypt");

async function exemplo() {


const senhaOriginal = "123456";

// Gerar hash
const hash = await [Link](senhaOriginal, 10); // 10 = custo (salt rounds)
[Link]("Hash gerado:", hash);

// Verificar senha
const match = await [Link]("123456", hash);
[Link]("Senha correta?", match);

const errado = await [Link]("senhaErrada", hash);


[Link]("Senha errada?", errado);
}

exemplo();

Saída:

Hash gerado: $2b$10$....


Senha correta? true
Senha errada? false

---

6 Integrando com Usuários (Mongo + Mongoose)

Model ([Link])

const { Schema, model } = require("mongoose");


const bcrypt = require("bcrypt");

const usuarioSchema = new Schema({


nome: String,
email: { type: String, required: true, unique: true },
senha: { type: String, required: true }
}, { timestamps: true });

// Antes de salvar, aplicar hash


[Link]("save", async function(next) {
if (![Link]("senha")) return next();
[Link] = await [Link]([Link], 10);
next();
});

// Método para comparar senha


[Link] = async function(senhaDigitada) {
return await [Link](senhaDigitada, [Link]);
};

const Usuario = model("Usuario", usuarioSchema);


[Link] = Usuario;

---

Controller ([Link])

const Usuario = require("../models/usuarioModel");

// Registrar usuário
async function registrar(req, res) {
try {
const { nome, email, senha } = [Link];
const novoUsuario = await [Link]({ nome, email, senha });
[Link](201).json({ mensagem: "Usuário registrado com sucesso", usuario: novoUsuario });
} catch (error) {
[Link](400).json({ erro: [Link] });
}
}

// Login
async function login(req, res) {
try {
const { email, senha } = [Link];
const usuario = await [Link]({ email });

if (!usuario) return [Link](404).json({ erro: "Usuário não encontrado" });

const senhaValida = await [Link](senha);


if (!senhaValida) return [Link](401).json({ erro: "Senha incorreta" });
[Link]({ mensagem: "Login bem-sucedido ", usuario });
} catch (error) {
[Link](500).json({ erro: [Link] });
}
}

[Link] = { registrar, login };

---

Rotas ([Link])

const express = require("express");


const router = [Link]();
const usuarioController = require("../controllers/usuarioController");

[Link]("/registrar", [Link]);
[Link]("/login", [Link]);

[Link] = router;

---

7 Testando

1. POST /usuarios/registrar

{ "nome": "Gabriel", "email": "gabriel@[Link]", "senha": "123456" }

No banco, a senha será armazenada em HASH.

2. POST /usuarios/login

{ "email": "gabriel@[Link]", "senha": "123456" }

Retorna sucesso.

3. Se tentar senha errada retorna erro.


---

8 Resumindo

Senhas nunca devem ser salvas em texto puro.


Hashing com bcrypt é o padrão de mercado.
Integramos hashing e validação de senha no Mongoose.
Agora temos registro e login básico com segurança.

---

Irmão, na próxima aula você prefere que a gente continue com JWT (JSON Web Token) para autenticação completa
com tokens, ou prefere antes ver como proteger rotas privadas (middleware de autenticação)?

Boa, irmão ! Agora vamos pra Super Aula 14 – JWT + Rotas Privadas.
Aqui a gente fecha o ciclo básico de autenticação moderna em [Link] com Express.

---

Super Aula 14 – Autenticação com JWT e Proteção de Rotas

---

1 O que é JWT?

JWT (JSON Web Token) é um token (cadeia de caracteres) usado para autenticação.

Ele tem 3 partes:

[Link]

Exemplo de token:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJpZCI6IjY2MjM2Yzg0MWM2NDM1NjM1Y2MzMTU4ZCIsImlhdCI6MTY5MzU5NzgzNX0
._hdU8TdqV6wWBgzxj0GL-4t5gQm8ZlDpUpZ4K1vJo0k

Header algoritmo usado.

Payload informações do usuário (ex.: id, email).

Signature assinatura que garante que não foi alterado.


---

2 Instalando dependências

npm install jsonwebtoken

---

3 Gerando Token no Login

Atualizar [Link]

const Usuario = require("../models/usuarioModel");


const jwt = require("jsonwebtoken");

const JWT_SECRET = "minha_chave_super_secreta"; // ideal usar variável de ambiente

// Registrar usuário (igual à aula anterior)


async function registrar(req, res) {
try {
const { nome, email, senha } = [Link];
const novoUsuario = await [Link]({ nome, email, senha });
[Link](201).json({ mensagem: "Usuário registrado", usuario: novoUsuario });
} catch (error) {
[Link](400).json({ erro: [Link] });
}
}

// Login com geração de token


async function login(req, res) {
try {
const { email, senha } = [Link];
const usuario = await [Link]({ email });

if (!usuario) return [Link](404).json({ erro: "Usuário não encontrado" });

const senhaValida = await [Link](senha);


if (!senhaValida) return [Link](401).json({ erro: "Senha incorreta" });

// Gerar token
const token = [Link](
{ id: usuario._id, email: [Link] }, // payload
JWT_SECRET,
{ expiresIn: "1h" } // expira em 1 hora
);

[Link]({ mensagem: "Login bem-sucedido ", token });


} catch (error) {
[Link](500).json({ erro: [Link] });
}
}

[Link] = { registrar, login };

---

4 Criando Middleware de Autenticação

Novo arquivo middlewares/[Link]

const jwt = require("jsonwebtoken");


const JWT_SECRET = "minha_chave_super_secreta";

function autenticarToken(req, res, next) {


const authHeader = [Link]["authorization"];
const token = authHeader && [Link](" ")[1]; // formato "Bearer token"

if (!token) return [Link](401).json({ erro: "Token não fornecido" });

[Link](token, JWT_SECRET, (err, usuario) => {


if (err) return [Link](403).json({ erro: "Token inválido" });
[Link] = usuario; // salva os dados do token na requisição
next();
});
}

[Link] = autenticarToken;

---

5 Criando Rota Privada

Atualizar [Link]

const express = require("express");


const router = [Link]();
const usuarioController = require("../controllers/usuarioController");
const autenticarToken = require("../middlewares/authMiddleware");

// Rotas públicas
[Link]("/registrar", [Link]);
[Link]("/login", [Link]);

// Rota protegida
[Link]("/perfil", autenticarToken, (req, res) => {
[Link]({ mensagem: "Acesso autorizado ", usuario: [Link] });
});

[Link] = router;

---

6 Testando no Insomnia/Postman

1. Registrar usuário

POST /usuarios/registrar
{
"nome": "Gabriel",
"email": "gabriel@[Link]",
"senha": "123456"
}

2. Login (gera token)

POST /usuarios/login
{
"email": "gabriel@[Link]",
"senha": "123456"
}

Resposta:

{ "mensagem": "Login bem-sucedido ", "token": "eyJhbGciOi..." }

3. Acessar rota privada

GET /usuarios/perfil
Headers: Authorization: Bearer SEU_TOKEN_AQUI
Resposta:

{
"mensagem": "Acesso autorizado ",
"usuario": { "id": "66236c841c...", "email": "gabriel@[Link]", "iat":..., "exp":... }
}

---

7 Resumindo

Aprendemos o que é JWT.


Login agora retorna token de autenticação.
Criamos middleware para verificar token.
Rotas privadas só funcionam com usuário autenticado.

---

Irmão, fechamos JWT + rotas privadas.


Na próxima aula, você quer que a gente veja refresh tokens (para renovar JWT expirado) ou já passamos para
autorização por papéis (roles), tipo admin/usuário?

Boa, irmão ! Agora vamos para a Super Aula 15 – Middlewares de Autenticação + Refresh Token + Logout Seguro.
Essa aula fecha o ciclo básico de segurança/autenticação profissional em APIs com [Link].

---

Super Aula 15 – Autenticação Avançada: Refresh Tokens & Logout

---

1 Problema com JWT tradicional

O JWT simples que fizemos tem um prazo de validade (expiresIn).

Se colocarmos expiração longa risco maior em caso de vazamento.

Se colocarmos expiração curta o usuário é desconectado rápido demais.


Solução: Refresh Token

Access Token (curto prazo) usado em cada requisição.

Refresh Token (longo prazo) usado só para pedir um novo access token.

---

2 Estrutura de Tokens

Access Token: expira em ~15min a 1h.

Refresh Token: expira em ~7 dias ou mais.

Guardamos Refresh Token no servidor ou no banco para poder invalidar no logout.

---

3 Ajustando dependências

Se ainda não tiver:

npm install jsonwebtoken

---

4 Criando Login com Access + Refresh Token

[Link]

const Usuario = require("../models/usuarioModel");


const jwt = require("jsonwebtoken");

const JWT_SECRET = "minha_chave_super_secreta";


const JWT_REFRESH_SECRET = "minha_chave_refresh_super_secreta";

// Armazena refresh tokens válidos (ideal: usar banco Redis ou Mongo)


let refreshTokens = [];

// Registrar (igual antes)


async function registrar(req, res) {
try {
const { nome, email, senha } = [Link];
const novoUsuario = await [Link]({ nome, email, senha });
[Link](201).json({ mensagem: "Usuário registrado", usuario: novoUsuario });
} catch (error) {
[Link](400).json({ erro: [Link] });
}
}

// Login
async function login(req, res) {
try {
const { email, senha } = [Link];
const usuario = await [Link]({ email });
if (!usuario) return [Link](404).json({ erro: "Usuário não encontrado" });

const senhaValida = await [Link](senha);


if (!senhaValida) return [Link](401).json({ erro: "Senha incorreta" });

// Access Token
const accessToken = [Link](
{ id: usuario._id, email: [Link] },
JWT_SECRET,
{ expiresIn: "15m" }
);

// Refresh Token
const refreshToken = [Link](
{ id: usuario._id, email: [Link] },
JWT_REFRESH_SECRET,
{ expiresIn: "7d" }
);
[Link](refreshToken);

[Link]({ accessToken, refreshToken });


} catch (error) {
[Link](500).json({ erro: [Link] });
}
}

---

5 Middleware de Autenticação

middlewares/[Link]
const jwt = require("jsonwebtoken");
const JWT_SECRET = "minha_chave_super_secreta";

function autenticarToken(req, res, next) {


const authHeader = [Link]["authorization"];
const token = authHeader && [Link](" ")[1];
if (!token) return [Link](401).json({ erro: "Token não fornecido" });

[Link](token, JWT_SECRET, (err, usuario) => {


if (err) return [Link](403).json({ erro: "Token inválido ou expirado" });
[Link] = usuario;
next();
});
}

[Link] = autenticarToken;

---

6 Rota de Refresh Token

[Link]

// Refresh
function refresh(req, res) {
const { token } = [Link];
if (!token) return [Link](401).json({ erro: "Refresh token obrigatório" });
if (![Link](token)) return [Link](403).json({ erro: "Refresh token inválido" });

[Link](token, JWT_REFRESH_SECRET, (err, usuario) => {


if (err) return [Link](403).json({ erro: "Refresh token expirado" });

// Gera novo Access Token


const accessToken = [Link](
{ id: [Link], email: [Link] },
JWT_SECRET,
{ expiresIn: "15m" }
);

[Link]({ accessToken });


});
}
---

7 Logout Seguro

[Link]

function logout(req, res) {


const { token } = [Link];
refreshTokens = [Link](t => t !== token);
[Link]({ mensagem: "Logout realizado com sucesso " });
}

[Link] = { registrar, login, refresh, logout };

---

8 Atualizando Rotas

[Link]

const express = require("express");


const router = [Link]();
const usuarioController = require("../controllers/usuarioController");
const autenticarToken = require("../middlewares/authMiddleware");

// Públicas
[Link]("/registrar", [Link]);
[Link]("/login", [Link]);
[Link]("/refresh", [Link]);
[Link]("/logout", [Link]);

// Protegida
[Link]("/perfil", autenticarToken, (req, res) => {
[Link]({ mensagem: "Acesso autorizado ", usuario: [Link] });
});

[Link] = router;

---

9 Fluxo Final do Usuário

1. Login recebe accessToken (15min) + refreshToken (7d).


2. Requisições protegidas usam accessToken no header.

3. Se expirar o access token chama /refresh com o refreshToken.

4. Logout envia refreshToken e ele é removido (não pode ser reutilizado).

---

Resumindo

Entendeu por que usar refresh tokens.


Implementou login com access + refresh token.
Criou rota de refresh token.
Criou rota de logout seguro.

---

Mano, pra próxima aula de segurança, quer que eu prepare sobre Autorização por papéis (roles: admin, usuário,
moderador) ou prefere que eu te ensine a proteger melhor os dados sensíveis no banco (ex.: criptografia de dados além
da senha)?

Boa, irmão ! Agora vamos pra Super Aula 16 – Segurança Avançada em APIs: XSS, SQL Injection e Rate Limiting.
Aqui você vai ver como profissionais de backend protegem suas aplicações [Link]/Express contra ataques comuns.

---

Super Aula 16 – XSS, SQL Injection e Rate Limiting

---

1 XSS (Cross-Site Scripting)

O que é?
É quando o atacante injeta código JavaScript malicioso no navegador da vítima.
Exemplo:

<input value="<script>alert('Hackeado!')</script>">
Como prevenir em [Link]/Express?

Usar sanitize em entradas de usuário.

Evitar injetar dados sem tratamento em HTML.

Usar bibliotecas para higienizar dados.

Instalar bibliotecas de segurança:

npm install helmet xss-clean

Configuração no [Link]

const express = require("express");


const helmet = require("helmet");
const xss = require("xss-clean");

const app = express();

// Protege headers HTTP


[Link](helmet());

// Remove scripts maliciosos de inputs


[Link](xss());

[Link]([Link]());

[Link](3000, () => [Link]("Servidor seguro rodando "));

---

2 SQL Injection

O que é?
Quando o atacante envia comandos SQL maliciosos.
Exemplo:

SELECT * FROM usuarios WHERE email = '' OR '1'='1';

Como prevenir?

Usar ORMs/ODMs (Mongoose, Sequelize, Prisma).


Usar queries parametrizadas (nunca concatenar strings!).

Exemplo inseguro

const resultado = await [Link](


`SELECT * FROM usuarios WHERE email = '${[Link]}'`
);

Exemplo seguro (com parâmetros)

const resultado = await [Link](


"SELECT * FROM usuarios WHERE email = ?",
[[Link]]
);

Se usar Mongoose, já está protegido, pois o ODM converte consultas em operações seguras.

---

3 Rate Limiting (Limitar requisições)

O que é?
Impede que um usuário faça muitas requisições em pouco tempo protege contra ataques de força bruta e DoS.

Instalar:

npm install express-rate-limit

Configurar:

const rateLimit = require("express-rate-limit");

// Limita 100 requisições por 15 minutos por IP


const limiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 100,
message: "Muitas requisições deste IP, tente novamente mais tarde "
});

[Link](limiter);

---
4 Bônus: Outras práticas de segurança

Usar HTTPS sempre (já vimos antes).


Armazenar variáveis sensíveis no .env.
Usar CORS configurado (não abrir para todos os domínios).
Validar dados com Joi ou Zod antes de salvar no banco.

---

5 Resumindo

XSS higienizar entradas (helmet, xss-clean).

SQL Injection nunca concatenar strings, sempre usar parâmetros ou ORMs.

Rate Limiting limitar requisições por IP (express-rate-limit).

Com isso, sua API já sobe de nível profissional em segurança.

---

Irmão, agora me diz: na próxima aula de segurança você prefere que a gente veja CORS + CSRF Protection ou logs e
monitoramento de ataques em produção (com Morgan + Winston)?

Você também pode gostar