Boas Práticas de Express.js: Roteamento, Middlewares e Estrutura de APIs REST para Times Ágeis Já leu

Express.js: Fundamentos e Arquitetura Express.js é um framework web minimalista para Node.js que facilita a criação de servidores HTTP e APIs REST. Sua força reside na simplicidade: você constrói apenas o que precisa, sem abstrações desnecessárias. O framework é construído sobre o módulo nativo do Node.js, adicionando camadas de roteamento, middleware e utilitários que aceleram o desenvolvimento. Para começar, instale Express via npm: . Um servidor básico requer apenas alguns comandos para escutar requisições. A arquitetura do Express é orientada por middlewares — funções que processam requisições antes de chegarem à rota final. Compreender esse fluxo é essencial para dominar o framework. Roteamento: O Coração das APIs Definindo Rotas Básicas Rotas definem como sua API responde a diferentes URLs e métodos HTTP. Express fornece métodos diretos para GET, POST, PUT, DELETE e outros. Cada rota é composta por um caminho, um método HTTP e uma função callback que recebe e . Usuário ${req.params.id} atualizado Parâmetros e Query Strings Existem três

Express.js: Fundamentos e Arquitetura

Express.js é um framework web minimalista para Node.js que facilita a criação de servidores HTTP e APIs REST. Sua força reside na simplicidade: você constrói apenas o que precisa, sem abstrações desnecessárias. O framework é construído sobre o módulo nativo http do Node.js, adicionando camadas de roteamento, middleware e utilitários que aceleram o desenvolvimento.

Para começar, instale Express via npm: npm install express. Um servidor básico requer apenas alguns comandos para escutar requisições. A arquitetura do Express é orientada por middlewares — funções que processam requisições antes de chegarem à rota final. Compreender esse fluxo é essencial para dominar o framework.

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

app.listen(3000, () => {
  console.log('Servidor rodando na porta 3000');
});

Roteamento: O Coração das APIs

Definindo Rotas Básicas

Rotas definem como sua API responde a diferentes URLs e métodos HTTP. Express fornece métodos diretos para GET, POST, PUT, DELETE e outros. Cada rota é composta por um caminho, um método HTTP e uma função callback que recebe request e response.

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

// GET
app.get('/usuarios', (req, res) => {
  res.json({ message: 'Lista de usuários' });
});

// POST
app.post('/usuarios', (req, res) => {
  res.status(201).json({ message: 'Usuário criado' });
});

// PUT
app.put('/usuarios/:id', (req, res) => {
  res.json({ message: `Usuário ${req.params.id} atualizado` });
});

// DELETE
app.delete('/usuarios/:id', (req, res) => {
  res.status(204).send();
});

app.listen(3000);

Parâmetros e Query Strings

Existem três formas principais de capturar dados: parâmetros de rota (req.params), query strings (req.query) e body (req.body). Parâmetros de rota são valores obrigatórios na URL; query strings são opcionais e vêm após ?. O body contém dados estruturados enviados em POST/PUT.

// Parâmetro de rota: /produtos/123
app.get('/produtos/:id', (req, res) => {
  console.log(req.params.id); // "123"
  res.json({ id: req.params.id });
});

// Query string: /produtos?categoria=eletrônicos&preco=100
app.get('/produtos', (req, res) => {
  console.log(req.query.categoria); // "eletrônicos"
  console.log(req.query.preco);      // "100"
  res.json({ categoria: req.query.categoria });
});

// Body (requer middleware express.json())
app.post('/produtos', (req, res) => {
  console.log(req.body.nome); // dados do formulário
  res.json({ received: req.body });
});

Middlewares: Processamento em Cadeia

Middlewares são funções executadas entre a requisição e a resposta. Cada middleware pode modificar req e res, passar o controle para o próximo middleware via next() ou encerrar a requisição com uma resposta. Essa arquitetura permite separar responsabilidades como autenticação, validação e logging.

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

// Middleware global
app.use(express.json()); // Parse JSON automaticamente

// Middleware customizado de logging
app.use((req, res, next) => {
  console.log(`${new Date().toISOString()} - ${req.method} ${req.path}`);
  next(); // Passa para o próximo middleware
});

// Middleware de autenticação
const verificarToken = (req, res, next) => {
  const token = req.headers.authorization;
  if (!token) {
    return res.status(401).json({ erro: 'Token ausente' });
  }
  req.usuario = { id: 1, nome: 'João' }; // Simulado
  next();
};

// Usando middleware em rota específica
app.get('/dados-privados', verificarToken, (req, res) => {
  res.json({ mensagem: `Olá, ${req.usuario.nome}` });
});

// Middleware de erro (deve ser o último)
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({ erro: 'Erro interno do servidor' });
});

app.listen(3000);

Estrutura de APIs REST Profissional

Organização em Camadas

Uma API REST profissional separava responsabilidades em camadas: rotas, controllers e models. As rotas apenas mapeiam URLs para funções; controllers contêm a lógica de negócio; models representam dados. Essa estrutura facilita testes, manutenção e escalabilidade.

// routes/usuarios.js
const express = require('express');
const router = express.Router();
const usuariosController = require('../controllers/usuariosController');

router.get('/', usuariosController.listar);
router.post('/', usuariosController.criar);
router.get('/:id', usuariosController.obter);
router.put('/:id', usuariosController.atualizar);
router.delete('/:id', usuariosController.deletar);

module.exports = router;

// controllers/usuariosController.js
const usuarios = []; // Simulado

exports.listar = (req, res) => {
  res.json(usuarios);
};

exports.criar = (req, res) => {
  const novoUsuario = { id: Date.now(), ...req.body };
  usuarios.push(novoUsuario);
  res.status(201).json(novoUsuario);
};

exports.obter = (req, res) => {
  const usuario = usuarios.find(u => u.id == req.params.id);
  if (!usuario) return res.status(404).json({ erro: 'Não encontrado' });
  res.json(usuario);
};

exports.atualizar = (req, res) => {
  const usuario = usuarios.find(u => u.id == req.params.id);
  if (!usuario) return res.status(404).json({ erro: 'Não encontrado' });
  Object.assign(usuario, req.body);
  res.json(usuario);
};

exports.deletar = (req, res) => {
  const index = usuarios.findIndex(u => u.id == req.params.id);
  if (index === -1) return res.status(404).json({ erro: 'Não encontrado' });
  usuarios.splice(index, 1);
  res.status(204).send();
};

// app.js
const express = require('express');
const usuariosRouter = require('./routes/usuarios');
const app = express();

app.use(express.json());
app.use('/api/usuarios', usuariosRouter);

app.listen(3000);

Tratamento de Erros e Validação

Toda API robusta precisa validar dados recebidos e comunicar erros claramente. Use bibliotecas como joi ou express-validator para validação declarativa. Sempre retorne status HTTP apropriados: 400 para dados inválidos, 404 para não encontrado, 500 para erro do servidor.

const { body, validationResult } = require('express-validator');

app.post('/usuarios',
  body('email').isEmail(),
  body('idade').isInt({ min: 18 }),
  (req, res) => {
    const erros = validationResult(req);
    if (!erros.isEmpty()) {
      return res.status(400).json({ erros: erros.array() });
    }
    // Lógica de criação
    res.status(201).json({ success: true });
  }
);

Conclusão

Os três pilares do Express.js — roteamento bem organizado, middlewares para separar responsabilidades e estrutura em camadas — formam a base de qualquer API REST profissional. Domine o fluxo de requisição-resposta, use middlewares para código limpo e escalável, e organize suas rotas e controllers de forma lógica. Esses fundamentos aplicados transformam um projeto caótico em uma aplicação mantível e testável.

Referências


Artigos relacionados