Node.js: Express Básico

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

1. Do HTTP nativo ao Express

Alice passou três dias escrevendo uma API usando o módulo HTTP nativo, mas o código ficou extenso e difícil de manter — ela precisava analisar manualmente as URLs, escrever correspondências de rotas à mão e processar o corpo da solicitação linha por linha. Depois de mudar para o Express, ela conseguiu implementar a mesma funcionalidade em apenas 30 linhas de código, com rotas claramente definidas e middleware encadeado automaticamente, o que resultou em um aumento de 10 vezes na eficiência da manutenção.

Comparação entre o código HTTP nativo e o código do Express

Comparação HTTP nativo Express
Definição de rota Manual if/else Correspondência req.url Declarativa app.get('/path', fn)
Análise do corpo da solicitação Monitorar manualmente os eventos data/end e criar um buffer express.json() Feito em uma única linha
Resposta enviada res.writeHead() + res.end() res.json() / res.send()
Arquivo estático Ler o arquivo manualmente + definir o Content-Type express.static('public')
Middleware Sem suporte integrado app.use() Composição no estilo pipeline
Tamanho do código (para funcionalidade equivalente) ~80 linhas ~30 linhas


2. Instalação e “Hello World”

▶ Exemplo:(1) Inicializando o projeto e instalando o Express

BASH
mkdir my-express-app && cd my-express-app
npm init -y
npm install express

▶ Exemplo:(2) “Hello World” básico

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

app.get('/', (req, res) => {
  res.send('Hello World!');
});

app.listen(3000, () => {
  console.log('Server running at http://localhost:3000');
});
▶ Experimente
BASH
node app.js

Basta acessar http://localhost:3000 no seu navegador para visualizar Hello World!.

▶ Exemplo: Retornar uma resposta JSON

JAVASCRIPT
app.get('/api/hello', (req, res) => {
  res.json({ message: 'Hello from Express!', status: 'ok' });
});
▶ Experimente

▶ Exemplo: “Olá” com parâmetros de roteamento

JAVASCRIPT
app.get('/hello/:name', (req, res) => {
  res.send(`Hello, ${req.params.name}!`);
});
▶ Experimente

3. Métodos de roteamento

Referência rápida aos métodos de roteamento expresso

Método Objetivo Idempotência Cenários típicos
app.get() Obter recursos Sim Ver lista/detalhes
app.post() Criar recurso Não Enviar formulário/Adicionar registro
app.put() Atualização completa Sim Substituir registro inteiro
app.delete() Excluir recurso Sim Excluir registro
app.patch() Atualização parcial Não Modificar campos individuais
app.all() Correspondência com todos os métodos Pré-processamento geral

▶ Exemplo:(1) Roteamento no estilo RESTful

JAVASCRIPT
app.get('/users', (req, res) => { res.json({ users: [] }); });
app.post('/users', (req, res) => { res.status(201).json({ created: true }); });
app.put('/users/:id', (req, res) => { res.json({ updated: req.params.id }); });
app.remove('/users/:id', (req, res) => { res.json({ deleted: req.params.id }); });
▶ Experimente

(2) Correspondência de rotas

▶ Exemplo: Como ler parâmetros de consulta

JAVASCRIPT
app.get('/search', (req, res) => {
  const { q, page = '1' } = req.query;
  res.json({ keyword: q, page: Number(page) });
});
▶ Experimente

▶ Exemplo: Vários parâmetros de rota

JAVASCRIPT
app.get('/posts/:postId/comments/:commentId', (req, res) => {
  res.json(req.params);
});
▶ Experimente

4. O conceito de middleware

No cerne do design do Express está o pipeline de middleware — cada solicitação flui sequencialmente por uma série de funções, cada uma das quais pode ler ou modificar a solicitação e a resposta, ou encerrar a solicitação antecipadamente.

100%
flowchart LR
  A[Request Request] --> B[Middleware1<br/>Logging]
  B --> C[Middleware2<br/>JSONAnalysis]
  C --> D[Middleware3<br/>Authentication and Validation]
  D --> E[Route Handling<br/>Business Logic]
  E --> F[Response Response]

▶ Exemplo:(1) app.use() para registrar middleware

JAVASCRIPT
const logger = (req, res, next) => {
  console.log(`${req.method} ${req.url} - ${new Date().toISOString()}`);
  next();
};
app.use(logger);
▶ Experimente

(2) Ordem de execução do middleware

▶ Exemplo: Middleware de autenticação

JAVASCRIPT
const auth = (req, res, next) => {
  const token = req.headers['authorization'];
  if (!token) return res.status(401).json({ error: 'No token' });
  next();
};
app.use('/api', auth);
▶ Experimente

▶ Exemplo: Middleware de tratamento de erros

JAVASCRIPT
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({ error: 'Something went wrong!' });
});
▶ Experimente

5. Middleware integrado

Lista de middlewares integrados

Middleware Finalidade Implementação Configurações comuns
express.json() Análise do corpo da solicitação JSON app.use(express.json()) { limit: '10kb' }
express.urlencoded() Análise de corpos de solicitação codificados por URL app.use(express.urlencoded({ extended: true })) { extended: true/false }
express.static() Hospedagem de arquivos estáticos app.use(express.static('public')) { maxAge: '1d' }

▶ Exemplo:(1) Análise do corpo da solicitação com express.json()

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

app.post('/api/users', (req, res) => {
  console.log(req.body);
  res.json({ received: req.body });
});
▶ Experimente

(2) express.static() para servir arquivos estáticos

Estrutura prevista do projeto:

TEXT 📖 Somente leitura
my-express-app/
├── public/
│   ├── index.html
│   └── style.css
├── app.js
└── package.json
JAVASCRIPT
app.use(express.static('public'));

Acesse http://localhost:3000/index.html para carregar arquivos estáticos diretamente.

▶ Exemplo: Hospedagem estática com vários diretórios

JAVASCRIPT
app.use(express.static('public'));
app.use('/uploads', express.static('uploads'));
▶ Experimente

▶ Exemplo: Limitando o tamanho do corpo de uma solicitação JSON

JAVASCRIPT
app.use(express.json({ limit: '100kb' }));
▶ Experimente

6. Recarga automática com o nodemon

Comparação entre o nodemon e o node

Item de comparação node nodemon
Após alterações no arquivo Reinício manual Reinício automático
Método de instalação Embutido npm i -D nodemon
Comando de inicialização node app.js npx nodemon app.js
Ambiente de produção Aplicável Não aplicável
Diretório de observação Nenhum Padrão: diretório atual; configurável

▶ Exemplo:(1) Instalação e uso

BASH
npm install --save-dev nodemon
npx nodemon app.js

▶ Exemplo:(2) Configurando scripts no arquivo package.json

JAVASCRIPT
{
  "scripts": {
    "dev": "nodemon app.js",
    "start": "node app.js"
  }
}
▶ Experimente

Use npm run dev (recarregamento automático) durante o desenvolvimento e npm start (operação estável) na produção.

▶ Exemplo: Diretório de monitoramento personalizado

BASH
npx nodemon --watch src --ext js,ets app.js


7. Exemplo completo: Aplicativo com a API Express

Vamos reunir todos os conceitos abordados até agora e criar, do zero, um aplicativo de API completo em pequena escala.

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

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

let todos = [
  { id: 1, task: 'Learn Express', done: false },
  { id: 2, task: 'Build an API', done: false },
];

app.get('/api/todos', (req, res) => res.json(todos));

app.post('/api/todos', (req, res) => {
  const todo = { id: todos.length + 1, ...req.body, done: false };
  todos.push(todo);
  res.status(201).json(todo);
});

app.put('/api/todos/:id', (req, res) => {
  const idx = todos.findIndex(t => t.id === Number(req.params.id));
  if (idx === -1) return res.status(404).json({ error: 'Not found' });
  todos[idx] = { ...todos[idx], ...req.body };
  res.json(todos[idx]);
});

app.delete('/api/todos/:id', (req, res) => {
  todos = todos.filter(t => t.id !== Number(req.params.id));
  res.json({ deleted: true });
});

app.listen(3000, () => console.log('API running at http://localhost:3000'));

Assim que estiver em funcionamento, você poderá acessar as páginas estáticas por meio de um navegador e usar a ferramenta da API para realizar operações CRUD no /api/todos.


❓ Perguntas Frequentes

P: Qual é a diferença entre o Express e o Koa? R: O Express é baseado em middleware de callback e possui um ecossistema rico; o Koa é baseado em assíncrono/await e é mais leve. Para iniciantes, o Express é a melhor opção, pois seu ecossistema é mais maduro.

P: Qual é a diferença entre app.use e app.get? R: app.use corresponde a todos os métodos de solicitação e é comumente usado para middleware; app.get corresponde apenas a solicitações GET e é usado para definir rotas.

P: Qual é a ordem de execução do middleware? R: O middleware é executado na ordem em que é registrado por meio de app.use ou app.get. A chamada de next() passa para o próximo middleware; se next() não for chamado, a execução é encerrada.

P: Como faço para lidar com um erro 404? R: Registre um middleware sem caminho após todas as rotas para gerar um erro 404 e encaminhá-lo ao middleware de tratamento de erros.

P: O Express consegue lidar com concorrência? R: O Express, por si só, é monotread, mas o loop de eventos do Node.js permite que ele lide com a concorrência de E/S de forma eficiente; tarefas que exigem muito da CPU requerem threads de trabalho.

P: O Express é a única opção? R: Não. O Koa é mais leve, o Fastify é mais rápido e o Hono oferece suporte à computação de ponta, mas o Express possui o ecossistema mais maduro e o maior número de recursos de aprendizagem, o que o torna a melhor opção para iniciantes.

P: É necessário chamar express.json() antes do route? R: Sim, app.use(express.json()) deve ser escrito antes do route; caso contrário, req.body se tornará undefined, pois o middleware é executado na ordem em que é registrado.

P: Qual é a diferença entre as versões 4.x e 5.x? R: O Express 5.x remove APIs obsoletas (como app.del), aprimora a correspondência de rotas (com suporte para path-to-regexp v8) e torna alguns comportamentos mais adequados para a programação assíncrona, mas o uso básico permanece praticamente o mesmo.

P: Como faço para reiniciar o serviço automaticamente? R: Instale o nodemon (npm i -D nodemon), inicie-o com o npx nodemon app.js e ele será reiniciado automaticamente após o arquivo ser salvo — o que é muito eficiente durante o desenvolvimento.

P: Qual é a diferença entre app.use e app.get? R: app.use corresponde a todos os métodos HTTP e ao prefixo do caminho (/api corresponde a /api/anything), enquanto app.get corresponde apenas ao método GET e exige uma correspondência exata do caminho. O primeiro é usado para middleware, e o segundo é usado para roteamento.

P: O que significa a opção extended no express.urlencoded? R: extended: true usa a biblioteca qs para análise sintática (suporta objetos aninhados), extended: false usa a biblioteca querystring (não suporta objetos aninhados) e true geralmente é suficiente para envios de formulários.


📖 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 lição com o conteúdo das lições 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%