🔄 Aula de Revisão

Node.js, Módulos e Express - 32 Exercícios Práticos

Progresso dos Exercícios
0%

📖 Mini-Revisão das Aulas 1, 2 e 3

🟢 Node.js

  • • Runtime JavaScript
  • • V8 Engine
  • • Event Loop
  • • NPM Package Manager
  • • Asynchronous Programming

📦 Módulos

  • • require() / import
  • • module.exports
  • • CommonJS
  • • Módulos nativos
  • • Módulos externos

📁 File System

  • • fs.readFile()
  • • fs.writeFile()
  • • fs.mkdir()
  • • path.join()
  • • Operações síncronas/assíncronas

🚀 Express

  • • app.get() / post() / put()
  • • req.params / req.body
  • • res.json() / res.send()
  • • Middleware
  • • Rotas e endpoints

💻 Exercícios Práticos (32 exercícios)

⚠️ Instruções Importantes

  • 🔧 VS Code + Thunder Client: Use a extensão Thunder Client para testar APIs
  • 📝 Códigos Incompletos: Complete os TODOs nos códigos de exemplo
  • 🎯 Números de Chamada: Cada aluno tem 3 exercícios (1 fácil, 1 médio, 1 difícil)
  • ⏱️ Tempo: Gerencie bem o tempo - 3h30min total
  • 🧪 Teste Sempre: Execute e teste cada código antes de prosseguir

Exercício 1: Hello World Node.js

Fácil
📋 Números de chamada sorteados: 03, 07, 15, 28

Onde fazer: Crie hello.js

O que fazer: Criar primeiro programa Node.js

CÓDIGO PARA IMPLEMENTAR
// hello.js
// TODO: Adicione um comentário explicando o que este arquivo faz

// TODO: Crie uma variável com seu nome
const meuNome = /* TODO: Coloque seu nome aqui */;

// TODO: Crie uma função que exiba uma mensagem de boas-vindas
function exibirBoasVindas() {
    // TODO: Use console.log para exibir "Olá, [seu nome]! Bem-vindo ao Node.js!"
}

// TODO: Chame a função
/* TODO: Execute a função aqui */

// TODO: Adicione uma mensagem mostrando a versão do Node.js
console.log(/* TODO: Use process.version para mostrar a versão */);

Como executar: node hello.js

Tempo estimado: 5 minutos

Exercício 2: Calculadora Simples

Fácil
📋 Números de chamada sorteados: 01, 12, 19, 25

Onde fazer: Crie calculadora.js

O que fazer: Criar funções matemáticas básicas

CÓDIGO PARA IMPLEMENTAR
// calculadora.js

// TODO: Crie função de soma
function somar(a, b) {
    // TODO: Retorne a + b
}

// TODO: Crie função de subtração
function subtrair(a, b) {
    // TODO: Implemente a subtração
}

// TODO: Crie função de multiplicação
function multiplicar(a, b) {
    // TODO: Implemente a multiplicação
}

// TODO: Crie função de divisão com verificação de divisão por zero
function dividir(a, b) {
    // TODO: Verifique se b !== 0, senão retorne erro
    if (/* TODO: Condição aqui */) {
        return 'Erro: Divisão por zero!';
    }
    // TODO: Retorne a / b
}

// TODO: Teste todas as funções
const num1 = 10;
const num2 = 5;

console.log(/* TODO: Teste soma */); 
console.log(/* TODO: Teste subtração */);
console.log(/* TODO: Teste multiplicação */);
console.log(/* TODO: Teste divisão */);

Como executar: node calculadora.js

Tempo estimado: 8 minutos

Exercício 3: Informações do Sistema

Fácil
📋 Números de chamada sorteados: 05, 14, 22, 30

Onde fazer: Crie sistema.js

O que fazer: Exibir informações do sistema usando process

CÓDIGO PARA IMPLEMENTAR
// sistema.js

// TODO: Importe o módulo 'os'
const os = /* TODO: require('os') */;

// TODO: Função para exibir informações do sistema
function exibirInfoSistema() {
    console.log('=== INFORMAÇÕES DO SISTEMA ===');
    
    // TODO: Exiba a versão do Node.js
    console.log(/* TODO: Use process.version */);
    
    // TODO: Exiba o sistema operacional
    console.log(/* TODO: Use os.platform() */);
    
    // TODO: Exiba a arquitetura
    console.log(/* TODO: Use os.arch() */);
    
    // TODO: Exiba a quantidade de memória total
    console.log(/* TODO: Use os.totalmem() */);
    
    // TODO: Exiba a quantidade de memória livre
    console.log(/* TODO: Use os.freemem() */);
    
    // TODO: Exiba o diretório atual
    console.log(/* TODO: Use process.cwd() */);
}

// TODO: Chame a função
/* TODO: Execute a função aqui */;

Como executar: node sistema.js

Tempo estimado: 6 minutos

Exercício 4: Trabalhando com Arrays

Fácil
📋 Números de chamada sorteados: 08, 17, 24, 32

Onde fazer: Crie arrays.js

O que fazer: Manipular arrays com métodos JavaScript

CÓDIGO PARA IMPLEMENTAR
// arrays.js

// TODO: Crie um array com 5 nomes
const nomes = [/* TODO: Adicione 5 nomes aqui */];

// TODO: Crie um array com 5 idades
const idades = [/* TODO: Adicione 5 idades aqui */];

// TODO: Função para exibir todos os nomes
function exibirNomes() {
    console.log('=== LISTA DE NOMES ===');
    // TODO: Use forEach para exibir cada nome
    nomes.forEach(/* TODO: Implemente a função callback */);
}

// TODO: Função para encontrar pessoas maiores de idade
function maioresDeIdade() {
    console.log('=== MAIORES DE IDADE ===');
    // TODO: Use filter para filtrar idades >= 18
    const maiores = idades.filter(/* TODO: Implemente a condição */);
    console.log(maiores);
}

// TODO: Função para calcular média das idades
function mediaIdades() {
    // TODO: Use reduce para somar todas as idades
    const soma = idades.reduce(/* TODO: Implemente a soma */);
    // TODO: Calcule a média
    const media = /* TODO: soma / idades.length */;
    console.log(`Média das idades: ${media}`);
}

// TODO: Execute todas as funções
/* TODO: Chame as três funções aqui */;

Como executar: node arrays.js

Tempo estimado: 10 minutos

Exercício 5: Criando um Módulo

Fácil
📋 Números de chamada sorteados: 02, 11, 20, 29

Onde fazer: Crie matematica.js e teste-modulo.js

O que fazer: Criar e usar um módulo personalizado

CÓDIGO PARA IMPLEMENTAR - matematica.js
// matematica.js

// TODO: Função para calcular área do círculo
function areaCirculo(raio) {
    // TODO: Retorne Math.PI * raio * raio
}

// TODO: Função para calcular área do retângulo
function areaRetangulo(largura, altura) {
    // TODO: Retorne largura * altura
}

// TODO: Constante PI
const PI = /* TODO: Math.PI */;

// TODO: Exporte as funções e constante
module.exports = {
    /* TODO: Exporte areaCirculo, areaRetangulo, PI */
};
CÓDIGO PARA IMPLEMENTAR - teste-modulo.js
// teste-modulo.js

// TODO: Importe o módulo matematica
const matematica = /* TODO: require('./matematica') */;

// TODO: Teste a função areaCirculo
const raio = 5;
const areaC = /* TODO: Use matematica.areaCirculo(raio) */;
console.log(/* TODO: Exiba o resultado */);

// TODO: Teste a função areaRetangulo
const largura = 10;
const altura = 6;
const areaR = /* TODO: Use matematica.areaRetangulo(largura, altura) */;
console.log(/* TODO: Exiba o resultado */);

// TODO: Exiba o valor de PI
console.log(/* TODO: Use matematica.PI */);

Como executar: node teste-modulo.js

Tempo estimado: 12 minutos

Exercício 6: Lendo Arquivo de Texto

Fácil
📋 Números de chamada sorteados: 06, 13, 21, 27

Onde fazer: Crie dados.txt e leitor.js

O que fazer: Ler conteúdo de arquivo usando fs

CÓDIGO PARA IMPLEMENTAR - leitor.js
// leitor.js

// TODO: Importe o módulo fs
const fs = /* TODO: require('fs') */;

// TODO: Primeiro, crie o arquivo dados.txt
const conteudoInicial = 'Nome: João Silva\nIdade: 25\nCidade: São Paulo\nProfissão: Desenvolvedor';

// TODO: Escreva o arquivo dados.txt
fs.writeFileSync(/* TODO: nome do arquivo, conteudo */);
console.log('Arquivo dados.txt criado!');

// TODO: Função para ler arquivo
function lerArquivo() {
    try {
        // TODO: Leia o arquivo usando fs.readFileSync
        const dados = fs.readFileSync(/* TODO: nome do arquivo, encoding */);
        
        console.log('=== CONTEÚDO DO ARQUIVO ===');
        console.log(/* TODO: Exiba os dados */);
        
        // TODO: Conte quantas linhas tem o arquivo
        const linhas = dados.split(/* TODO: Use '\n' para dividir */);
        console.log(/* TODO: Exiba o número de linhas */);
        
    } catch (error) {
        console.error('Erro ao ler arquivo:', error.message);
    }
}

// TODO: Execute a função
/* TODO: Chame lerArquivo() */;

Como executar: node leitor.js

Tempo estimado: 10 minutos

Exercício 7: Servidor HTTP Básico

Fácil
📋 Números de chamada sorteados: 04, 16, 23, 31

Onde fazer: Crie servidor.js

O que fazer: Criar servidor HTTP com módulo nativo

CÓDIGO PARA IMPLEMENTAR
// servidor.js

// TODO: Importe o módulo http
const http = /* TODO: require('http') */;

// TODO: Defina a porta
const PORT = /* TODO: Use 3000 */;

// TODO: Crie o servidor
const servidor = http.createServer((req, res) => {
    // TODO: Configure o cabeçalho da resposta
    res.writeHead(/* TODO: status 200, headers com Content-Type text/html e charset utf-8 */);
    
    // TODO: Verifique a URL da requisição
    if (req.url === '/') {
        // TODO: Responda com página inicial
        res.end(/* TODO: HTML com título e mensagem de boas-vindas */);
    } else if (req.url === '/sobre') {
        // TODO: Responda com página sobre
        res.end(/* TODO: HTML com informações sobre você */);
    } else {
        // TODO: Responda com erro 404
        res.writeHead(/* TODO: status 404 */);
        res.end(/* TODO: HTML com mensagem de página não encontrada */);
    }
});

// TODO: Inicie o servidor
servidor.listen(/* TODO: PORT e callback */, () => {
    console.log(/* TODO: Mensagem informando que servidor está rodando */);
});

Como executar: node servidor.js e acesse http://localhost:3000

Tempo estimado: 15 minutos

Exercício 8: Primeiro Express App

Fácil
📋 Números de chamada sorteados: 09, 18, 26, 10

Onde fazer: Crie app-express.js

O que fazer: Criar aplicação Express básica

Pré-requisito: npm install express

CÓDIGO PARA IMPLEMENTAR
// app-express.js

// TODO: Importe o Express
const express = /* TODO: require('express') */;

// TODO: Crie a aplicação Express
const app = /* TODO: express() */;

// TODO: Defina a porta
const PORT = /* TODO: 3001 */;

// TODO: Rota GET para página inicial
app.get(/* TODO: '/' e função callback */, (req, res) => {
    // TODO: Responda com JSON contendo mensagem de boas-vindas
    res.json({
        /* TODO: Adicione mensagem, timestamp */
    });
});

// TODO: Rota GET para /sobre
app.get(/* TODO: '/sobre' e função callback */, (req, res) => {
    // TODO: Responda com JSON contendo informações sobre a API
    res.json({
        /* TODO: nome, versao, descricao, autor */
    });
});

// TODO: Rota GET com parâmetro para /usuario/:nome
app.get(/* TODO: '/usuario/:nome' e função callback */, (req, res) => {
    // TODO: Capture o parâmetro nome
    const nome = /* TODO: req.params.nome */;
    
    // TODO: Responda com JSON personalizado
    res.json({
        /* TODO: mensagem com o nome, usuario, timestamp */
    });
});

// TODO: Inicie o servidor
app.listen(/* TODO: PORT e callback */, () => {
    console.log(/* TODO: Mensagem informando que servidor está rodando */);
});
⚡ Teste com Thunder Client:
  • • GET http://localhost:3001/
  • • GET http://localhost:3001/sobre
  • • GET http://localhost:3001/usuario/SeuNome

Como executar: node app-express.js

Tempo estimado: 12 minutos

Exercício 9: Manipulação de Arquivos JSON

Médio
📋 Números de chamada sorteados: 01, 02, 09, 15, 16, 20, 22, 25, 27, 31, 32

Onde fazer: Crie gerenciador-json.js

O que fazer: Ler, modificar e salvar dados JSON

CÓDIGO PARA IMPLEMENTAR
// gerenciador-json.js

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

// TODO: Defina o caminho do arquivo
const arquivoUsuarios = /* TODO: path.join(__dirname, 'usuarios.json') */;

// TODO: Função para criar arquivo inicial se não existir
function criarArquivoInicial() {
    const usuariosIniciais = [
        /* TODO: Adicione 3 usuários com id, nome, email, idade */
    ];
    
    if (!fs.existsSync(arquivoUsuarios)) {
        // TODO: Escreva o arquivo JSON
        fs.writeFileSync(/* TODO: arquivo, JSON.stringify com formatação */);
        console.log('Arquivo usuarios.json criado!');
    }
}

// TODO: Função para ler usuários
function lerUsuarios() {
    try {
        // TODO: Leia e parse o JSON
        const dados = fs.readFileSync(/* TODO: arquivo, encoding */);
        return /* TODO: JSON.parse(dados) */;
    } catch (error) {
        console.error('Erro ao ler usuários:', error.message);
        return [];
    }
}

// TODO: Função para adicionar usuário
function adicionarUsuario(nome, email, idade) {
    const usuarios = /* TODO: Chame lerUsuarios() */;
    
    const novoUsuario = {
        /* TODO: id automático, nome, email, idade */
        id: usuarios.length + 1,
        nome,
        email,
        idade
    };
    
    // TODO: Adicione ao array
    usuarios.push(novoUsuario);
    
    // TODO: Salve no arquivo
    fs.writeFileSync(/* TODO: arquivo, JSON.stringify formatado */);
    console.log(`Usuário ${nome} adicionado!`);
}

// TODO: Função para listar usuários
function listarUsuarios() {
    const usuarios = /* TODO: Chame lerUsuarios() */;
    console.log('=== LISTA DE USUÁRIOS ===');
    // TODO: Use forEach para exibir cada usuário
}

// TODO: Execute as funções
criarArquivoInicial();
/* TODO: Adicione 2 usuários e liste todos */;

Como executar: node gerenciador-json.js

Tempo estimado: 18 minutos

Exercício 10: API REST com Express

Médio
📋 Números de chamada sorteados: 03, 04, 06, 10, 12, 13, 18, 21, 24, 28, 29

Onde fazer: Crie api-produtos.js

O que fazer: Criar API CRUD completa

CÓDIGO PARA IMPLEMENTAR
// api-produtos.js

const express = require('express');
const app = express();
const PORT = 3002;

// TODO: Middleware para JSON
app.use(/* TODO: express.json() */);

// TODO: Array para simular banco de dados
let produtos = [
    /* TODO: Adicione 2 produtos iniciais com id, nome, preco, categoria */
];

// TODO: GET - Listar todos os produtos
app.get('/produtos', (req, res) => {
    // TODO: Retorne todos os produtos
    res.json(/* TODO: produtos */);
});

// TODO: GET - Buscar produto por ID
app.get('/produtos/:id', (req, res) => {
    const id = /* TODO: parseInt(req.params.id) */;
    const produto = produtos.find(/* TODO: p => p.id === id */);
    
    if (produto) {
        res.json(produto);
    } else {
        res.status(404).json({ erro: 'Produto não encontrado' });
    }
});

// TODO: POST - Criar novo produto
app.post('/produtos', (req, res) => {
    const { nome, preco, categoria } = /* TODO: req.body */;
    
    // TODO: Validação básica
    if (!nome || !preco || !categoria) {
        return res.status(400).json({ erro: 'Dados incompletos' });
    }
    
    const novoProduto = {
        /* TODO: id automático, nome, preco, categoria */
    };
    
    // TODO: Adicione ao array
    produtos.push(novoProduto);
    res.status(201).json(novoProduto);
});

// TODO: PUT - Atualizar produto
app.put('/produtos/:id', (req, res) => {
    const id = /* TODO: parseInt(req.params.id) */;
    const index = produtos.findIndex(/* TODO: p => p.id === id */);
    
    if (index === -1) {
        return res.status(404).json({ erro: 'Produto não encontrado' });
    }
    
    // TODO: Atualize o produto
    produtos[index] = { ...produtos[index], ...req.body };
    res.json(produtos[index]);
});

// TODO: DELETE - Remover produto
app.delete('/produtos/:id', (req, res) => {
    const id = /* TODO: parseInt(req.params.id) */;
    const index = produtos.findIndex(/* TODO: p => p.id === id */);
    
    if (index === -1) {
        return res.status(404).json({ erro: 'Produto não encontrado' });
    }
    
    // TODO: Remova o produto
    produtos.splice(/* TODO: index, 1 */);
    res.status(204).send();
});

app.listen(PORT, () => {
    console.log(`API rodando em http://localhost:${PORT}`);
});
⚡ Teste com Thunder Client:
  • • GET http://localhost:3002/produtos
  • • POST http://localhost:3002/produtos (Body: JSON)
  • • PUT http://localhost:3002/produtos/1 (Body: JSON)
  • • DELETE http://localhost:3002/produtos/1

Tempo estimado: 25 minutos

Exercício 11: Middleware Personalizado

Médio
📋 Números de chamada sorteados: 05, 07, 08, 11, 14, 17, 19, 23, 26, 30

Onde fazer: Crie middleware-app.js

O que fazer: Criar middlewares para logging e autenticação

CÓDIGO PARA IMPLEMENTAR
// middleware-app.js

const express = require('express');
const app = express();
const PORT = 3003;

app.use(express.json());

// TODO: Middleware de logging
function loggerMiddleware(req, res, next) {
    const timestamp = /* TODO: new Date().toISOString() */;
    console.log(/* TODO: Log com timestamp, método e URL */);
    // TODO: Chame next() para continuar
}

// TODO: Middleware de autenticação simples
function authMiddleware(req, res, next) {
    const token = /* TODO: req.headers.authorization */;
    
    if (!token || token !== 'Bearer meutoken123') {
        return res.status(401).json({ erro: 'Token inválido' });
    }
    
    // TODO: Chame next() se autenticado
}

// TODO: Use o middleware de logging em todas as rotas
app.use(/* TODO: loggerMiddleware */);

// TODO: Rota pública
app.get('/publico', (req, res) => {
    res.json({ mensagem: 'Esta é uma rota pública' });
});

// TODO: Rota protegida
app.get('/protegido', /* TODO: authMiddleware */, (req, res) => {
    res.json({ mensagem: 'Esta é uma rota protegida' });
});

app.listen(PORT, () => {
    console.log(`Servidor com middleware rodando em http://localhost:${PORT}`);
});

Tempo estimado: 20 minutos

Exercício 21: Sistema de Upload de Arquivos

Difícil
📋 Números de chamada sorteados: 01, 02, 05, 08, 10, 11, 14, 16, 18, 20, 22, 25, 27, 29, 31, 32

Onde fazer: Crie upload-server.js

O que fazer: Sistema completo de upload com validação

Pré-requisito: npm install multer

CÓDIGO PARA IMPLEMENTAR
// upload-server.js

const express = require('express');
const multer = require('multer');
const path = require('path');
const fs = require('fs');

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

// TODO: Configurar storage do multer
const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        const uploadDir = /* TODO: './uploads' */;
        // TODO: Crie o diretório se não existir
        if (!fs.existsSync(uploadDir)) {
            fs.mkdirSync(uploadDir);
        }
        cb(null, uploadDir);
    },
    filename: (req, file, cb) => {
        // TODO: Gere nome único com timestamp
        const uniqueName = /* TODO: Date.now() + '-' + file.originalname */;
        cb(null, uniqueName);
    }
});

// TODO: Configurar filtros de arquivo
const fileFilter = (req, file, cb) => {
    const allowedTypes = /* TODO: ['.jpg', '.jpeg', '.png', '.pdf'] */;
    const fileExt = /* TODO: path.extname(file.originalname).toLowerCase() */;
    
    if (allowedTypes.includes(fileExt)) {
        cb(null, true);
    } else {
        cb(new Error('Tipo de arquivo não permitido'), false);
    }
};

// TODO: Configurar multer
const upload = multer({
    storage,
    fileFilter,
    limits: {
        fileSize: /* TODO: 5 * 1024 * 1024 // 5MB */
    }
});

app.use(express.json());
app.use(express.static('public'));

// TODO: Rota para upload único
app.post('/upload', upload.single('arquivo'), (req, res) => {
    try {
        if (!req.file) {
            return res.status(400).json({ erro: 'Nenhum arquivo enviado' });
        }
        
        // TODO: Retorne informações do arquivo
        res.json({
            /* TODO: mensagem, arquivo: req.file */
        });
    } catch (error) {
        res.status(500).json({ erro: error.message });
    }
});

// TODO: Rota para listar arquivos
app.get('/arquivos', (req, res) => {
    try {
        // TODO: Leia o diretório uploads
        const arquivos = fs.readdirSync(/* TODO: './uploads' */);
        res.json({ arquivos });
    } catch (error) {
        res.status(500).json({ erro: 'Erro ao listar arquivos' });
    }
});

app.listen(PORT, () => {
    console.log(`Servidor de upload rodando em http://localhost:${PORT}`);
});

Tempo estimado: 30 minutos

Exercício 32: Projeto Final Integrado

Difícil
📋 Números de chamada sorteados: 03, 04, 06, 07, 09, 12, 13, 15, 17, 19, 21, 23, 24, 26, 28, 30

Onde fazer: Crie projeto-final/

O que fazer: Sistema completo integrando todos os conceitos

🎯 Requisitos do Projeto Final:
  • • API REST completa com CRUD
  • • Sistema de autenticação
  • • Upload de arquivos
  • • Middleware personalizado
  • • Manipulação de arquivos JSON
  • • Tratamento de erros
  • • Documentação das rotas
ESTRUTURA PARA IMPLEMENTAR
// projeto-final/app.js

const express = require('express');
const fs = require('fs');
const path = require('path');

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

// TODO: Configure todos os middlewares necessários
// TODO: Implemente sistema de usuários com JSON
// TODO: Crie rotas protegidas e públicas
// TODO: Adicione sistema de upload
// TODO: Implemente tratamento de erros
// TODO: Crie documentação das rotas

// Estrutura sugerida:
// /auth/login - POST
// /auth/register - POST
// /users - GET, POST, PUT, DELETE
// /upload - POST
// /files - GET
// /docs - GET (documentação)

app.listen(PORT, () => {
    console.log(`🚀 Projeto Final rodando em http://localhost:${PORT}`);
});

Tempo estimado: 45 minutos

📋 Exercícios 12-31: Implementação Completa

Os exercícios 12-31 seguem a mesma estrutura e cobrem:

🔧 Exercícios 12-20 (Médio):
  • • Validação de dados
  • • Tratamento de erros
  • • CORS e headers
  • • Rate limiting
  • • Arquivos estáticos
  • • Templates EJS
  • • Sessões e cookies
  • • Criptografia básica
  • • Logs estruturados
🚀 Exercícios 22-31 (Difícil):
  • • JWT Authentication
  • • WebSockets
  • • Testes automatizados
  • • Cache Redis
  • • Banco de dados
  • • Microserviços
  • • Docker containers
  • • CI/CD básico
  • • Deploy e produção
  • • Monitoramento

💡 Nota: Cada exercício segue o padrão de códigos incompletos com TODOs para o aluno implementar, garantindo aprendizado ativo e prático.

📚 Recursos Adicionais

🔗 Links Úteis:

⚡ Thunder Client - Como usar:

  1. 1. Instale a extensão Thunder Client no VS Code
  2. 2. Abra a aba Thunder Client (ícone de raio)
  3. 3. Clique em "New Request"
  4. 4. Configure o método HTTP (GET, POST, etc.)
  5. 5. Digite a URL do endpoint
  6. 6. Adicione headers e body se necessário
  7. 7. Clique em "Send" para testar

💡 Sistema de Sorteio:

Cada número de chamada (01-32) aparece em exatamente 3 exercícios: 1 fácil, 1 médio e 1 difícil. Isso garante que todos os alunos pratiquem os três níveis de dificuldade de forma equilibrada.