Node.js: Rotas e Middleware

Última atualização: 2026-08-26

O projeto de API do Charlie tinha, inicialmente, apenas cinco rotas, todas escritas em app.js, o que ainda era bastante claro. Dois meses depois, o número de rotas havia crescido para 30, e o arquivo ultrapassou 500 linhas — demorava uma eternidade para fazer uma única alteração em um endpoint da API. A equipe decidiu usar express.Router() para dividir as rotas em módulos — as rotas de usuários foram para users.js, as de autenticação para auth.js e o middleware de log personalizado foi movido para um arquivo separado. Após a divisão, cada arquivo passou a ter uma única responsabilidade, e a eficiência da manutenção melhorou significativamente.

Você aprenderá:


1. express.Router() – Roteamento modular

À medida que o número de rotas aumenta, colocar todas as rotas em app.js pode resultar em arquivos muito grandes e dificultar a colaboração. express.Router() permite que você crie instâncias independentes de rotas e, em seguida, as monte em um prefixo de caminho específico em seu aplicativo.

Recurso Rotas definidas diretamente no aplicativo Roteamento modular por meio do módulo Router
Organização de arquivos Tudo no app.js Dividido em arquivos separados por módulo
Prefixo do caminho Especifique o caminho completo para cada raiz Defina um prefixo uniforme ao montar
Colaboração em equipe Vários usuários editando o mesmo arquivo Manutenção independente de cada módulo
Reutilização Baixa Alta; pode ser reutilizado em diferentes projetos

▶ Exemplo: Criação de um módulo de roteamento de usuários independente

JAVASCRIPT
// routes/users.js
const express = require('express');
const router = express.Router();

router.get('/', (req, res) => {
  res.json({ users: ['Alice', 'Bob'] });
});

router.get('/:id', (req, res) => {
  res.json({ user: req.params.id });
});

module.exports = router;
▶ Experimente

▶ Exemplo: Montagem de um módulo de rota no arquivo app.js

JAVASCRIPT
// app.js
const express = require('express');
const app = express();
const userRouter = require('./routes/users');

app.use('/users', userRouter);

app.listen(3000, () => {
  console.log('Server running on port 3000');
});
▶ Experimente

A visita a /users corresponde a router.get('/'), e a visita a /users/42 corresponde a router.get('/:id').



2. Parâmetros de rota, strings de consulta e corpos de solicitação

O Express oferece três formas de receber dados de clientes, cada uma adequada a diferentes cenários.

Fonte de dados Como acessar Exemplo de URL Usos típicos
Parâmetros de roteamento req.params /users/42 Identifica um recurso específico
String de consulta req.query /users?role=admin Filtrar, Ordenar, Pesquisar
Corpo da solicitação req.body Corpo da solicitação POST Enviar formulário/dados JSON

▶ Exemplo: Parâmetro de rota :id

JAVASCRIPT
app.get('/products/:id', (req, res) => {
  const productId = req.params.id;
  res.json({ productId });
});
▶ Experimente

▶ Exemplo: Consulta string req.query

JAVASCRIPT
app.get('/products', (req, res) => {
  const { category, sort, page } = req.query;
  res.json({ category, sort, page: page || 1 });
});
▶ Experimente

Acesse /products?category=electronics&sort=price&page=2, req.query e { category: 'electronics', sort: 'price', page: '2' }.

▶ Exemplo: Corpo da solicitação req.body e express.json()

JAVASCRIPT
app.use(express.json());

app.post('/products', (req, res) => {
  const { name, price } = req.body;
  res.status(201).json({ name, price });
});
▶ Experimente

Observação: Os valores de req.query e req.params são, ambos, cadeias de caracteres e devem ser convertidos manualmente em números.



3. Noções básicas sobre middleware e o mecanismo next()

O middleware é um conceito fundamental do Express — toda solicitação passa por uma cadeia de middleware, e cada função de middleware pode ler a solicitação, modificar a resposta ou passar o controle para a próxima função de middleware.

100%
graph LR
  A[Request] --> B[morgan Log]
  B --> C[express.json Analysis]
  C --> D[Custom auth Middleware]
  D --> E[Route Handling Functions]
  E --> F[Response]
  D -->|next error| G[Error-handling middleware]

▶ Exemplo: O middleware personalizado mais simples

JAVASCRIPT
function logger(req, res, next) {
  console.log(`${req.method} ${req.url} - ${new Date().toISOString()}`);
  next();
}

app.use(logger);
▶ Experimente
Regra Descrição
next() deve ser chamado Caso contrário, a solicitação será suspensa e o cliente nunca receberá uma resposta
A ordem de chamada é a ordem de execução O middleware registrado primeiro é executado primeiro
app.use() Aplica-se globalmente app.use('/api', ...) Aplica-se apenas ao caminho /api
next('route') Ignorar o middleware restante para a rota atual


4. Integração com middleware de terceiros

A comunidade oferece uma ampla variedade de middleware pronto para uso, que pode ser ativado com uma única linha de código após a instalação.

Middleware Finalidade Comando de instalação
cors Resolução de problemas com solicitações entre origens npm install cors
morgan Registro de solicitações HTTP npm install morgan
capacete Configurar um capacete de resposta de segurança npm install helmet
express-rate-limit Limite de taxa de solicitações npm install express-rate-limit
cookie-parser Analisar cookies npm install cookie-parser

▶ Exemplo: Integração de CORS, Morgan e Helmet

JAVASCRIPT
const cors = require('cors');
const morgan = require('morgan');
const helmet = require('helmet');

app.use(helmet());
app.use(cors());
app.use(morgan('combined'));
app.use(express.json());
▶ Experimente

Observação: Recomenda-se colocar o middleware relacionado à segurança (Helmet) em primeiro lugar, seguido imediatamente pelo middleware de registro de logs.



5. Middleware para tratamento de erros

Convenção Express: Uma função com quatro parâmetros (err, req, res, next) é um middleware de tratamento de erros. Sempre que algum middleware chama next(err), ele ignora o middleware regular subsequente e prossegue diretamente para o middleware de tratamento de erros.

Item de comparação Middleware padrão Middleware de tratamento de erros
Número de parâmetros 3 (req, res, next) 4 (err, req, res, next)
Método de acionamento Executar sequencialmente à medida que as solicitações chegam next(err) Acionamento
Local de inscrição Qualquer local Deve ser colocado por último
Pode haver mais de um? Sim Sim, executados em ordem

▶ Exemplo: Middleware de tratamento global de erros

JAVASCRIPT
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(err.status || 500).json({
    error: err.message || 'Internal Server Error'
  });
});
▶ Experimente

▶ Exemplo: Gerando um error em uma route

JAVASCRIPT
app.get('/admin', (req, res, next) => {
  const err = new Error('Access denied');
  err.status = 403;
  next(err);
});
▶ Experimente

6. Mermaid: Estrutura modular de roteamento do roteador

100%
graph TD
  APP[app.js] --> UR["/users → userRouter"]
  APP --> AR["/auth → authRouter"]
  APP --> MW["middleware/logger.js"]
  UR --> U1["GET / → User List"]
  UR --> U2["GET /:id → User Details"]
  UR --> U3["POST / → Create a User"]
  AR --> A1["POST /login → Log In"]
  AR --> A2["POST /register → Register"]
  MW --> ML["Logging Middleware"]


7. Exemplo abrangente: API de roteamento modular

Neste exemplo, o middleware de roteamento do usuário, o de autenticação e o de registro de log são divididos em arquivos separados e, por fim, integrados ao app.js.

▶ Exemplo: middleware/logger.js — Middleware de registro personalizado

JAVASCRIPT
function logger(req, res, next) {
  const start = Date.now();
  res.on('finish', () => {
    const duration = Date.now() - start;
    console.log(`${req.method} ${req.originalUrl} ${res.statusCode} ${duration}ms`);
  });
  next();
}

module.exports = logger;
▶ Experimente

▶ Exemplo: routes/users.js — Módulo de rotas do usuário

JAVASCRIPT
const express = require('express');
const router = express.Router();

let users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' }
];

router.get('/', (req, res) => {
  res.json(users);
});

router.get('/:id', (req, res, next) => {
  const user = users.find(u => u.id === parseInt(req.params.id));
  if (!user) {
    const err = new Error('User not found');
    err.status = 404;
    return next(err);
  }
  res.json(user);
});

router.post('/', (req, res) => {
  const { name } = req.body;
  if (!name) {
    return res.status(400).json({ error: 'Name is required' });
  }
  const newUser = { id: users.length + 1, name };
  users.push(newUser);
  res.status(201).json(newUser);
});

module.exports = router;
▶ Experimente

▶ Exemplo: routes/auth.js — Módulo de rotas de autenticação

JAVASCRIPT
const express = require('express');
const router = express.Router();

router.post('/login', (req, res) => {
  const { username, password } = req.body;
  if (!username || !password) {
    return res.status(400).json({ error: 'Username and password required' });
  }
  res.json({ message: 'Login successful', token: 'mock-jwt-token' });
});

router.post('/register', (req, res) => {
  const { username, email, password } = req.body;
  if (!username || !email || !password) {
    return res.status(400).json({ error: 'All fields are required' });
  }
  res.status(201).json({ message: 'Registration successful' });
});

module.exports = router;
▶ Experimente

▶ Exemplo: app.js — Ponto de entrada da integração

JAVASCRIPT
const express = require('express');
const helmet = require('helmet');
const cors = require('cors');
const morgan = require('morgan');

const logger = require('./middleware/logger');
const userRouter = require('./routes/users');
const authRouter = require('./routes/auth');

const app = express();

app.use(helmet());
app.use(cors());
app.use(morgan('combined'));
app.use(express.json());
app.use(logger);

app.use('/users', userRouter);
app.use('/auth', authRouter);

app.use((req, res) => {
  res.status(404).json({ error: 'Route not found' });
});

app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(err.status || 500).json({
    error: err.message || 'Internal Server Error'
  });
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});
▶ Experimente

Executar teste:

BASH
node app.js
TEXT 📖 Somente leitura
Server running on port 3000
GET /users 200 3ms
GET /users/1 200 2ms
POST /auth/login 200 5ms

❓ Perguntas Frequentes

P: O que acontece se next() não for chamado? R: A solicitação será suspensa, e o cliente nunca receberá uma resposta. É necessário chamar next() no middleware para passar o controle, ou usar métodos como res.end() ou res.json() para encerrar diretamente a resposta.

P: Qual é a diferença entre parâmetros de rota e parâmetros de consulta? R: Os parâmetros de rota fazem parte do caminho da URL, como o 42 em /users/:id, que pode ser recuperado usando req.params.id; os parâmetros de consulta são pares chave-valor que vêm após o ?, como em /users?role=admin, que podem ser recuperados usando req.query.role. Os primeiros identificam recursos, enquanto os segundos filtram recursos.

P: A ordem em que o middleware é registrado é importante? R: É muito importante. O Express executa o middleware na ordem em que ele é registrado. Por exemplo, express.json() deve ser registrado antes de qualquer rota que precise ler req.body; caso contrário, req.body será undefined.

P: Como faço para implementar o tratamento global de erros? R: Defina uma função com quatro argumentos (err, req, res, next) e registre-a com app.use() após todas as rotas e middlewares. Qualquer middleware que chamar next(err) será encaminhado para esse manipulador.

P: Que problema o middleware CORS resolve? R: A política de mesma origem do navegador bloqueia solicitações entre origens. O middleware CORS adiciona campos como Access-Control-Allow-Origin aos cabeçalhos de resposta, permitindo que aplicativos front-end de origens especificadas acessem a API.

P: Qual é a diferença entre express.Router() e usar app.get() diretamente? R: Router cria uma instância de roteador independente que pode ser montada em qualquer prefixo de rota, tornando-a adequada para modularização; app.get() é registrado diretamente na instância da aplicação, tornando-o adequado para projetos simples. Ambos são funcionalmente equivalentes; a diferença está na forma como são organizados.

P: Como posso modificar o objeto req em um middleware para passar dados para o processamento subsequente? R: Basta atribuir propriedades diretamente ao req, como req.user = { id: 1 }. Os middlewares e rotas subsequentes poderão então acessar esses dados por meio do req.user. Esse é um padrão comum para a comunicação entre middlewares no Express.


📖 Resumo


📝 Exercícios

  1. Conclua todos os exemplos de código desta lição e certifique-se de que cada um deles seja executado corretamente.
  2. Modifique o exemplo completo e adicione suas próprias extensões
  3. Analise a documentação oficial, identifique 1 ou 2 APIs que não foram abordadas nesta aula e escreva um código de teste para elas.
  4. Reflexão: Como você aplicaria o que aprendeu nesta aula a um projeto do mundo real?
  5. Tente combinar o que você aprendeu nesta aula com o conteúdo das aulas anteriores para criar um pequeno projeto.
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%