Node.js Framework

Express

Express é o framework web minimalista e não opinativo para Node.js. Uma rota, uma função e uma cadeia de middleware — esse é todo o modelo mental, e ele ainda sustenta uma enorme fatia da web.

beginner16 min readUpdated 16 de set. de 2026
server.js
js
// server.js
import express from "express";

const app = express();
app.use(express.json());

app.get("/users/:id", async (req, res, next) => {
  try {
    const user = await db.user.findById(req.params.id);
    if (!user) return res.status(404).json({ error: "not_found" });
    res.json(user);
  } catch (err) {
    next(err);
  }
});

app.listen(3000);
Lançado
2010
Roda em
Node.js
Estilo
Minimalista, não opinativo
Ideia central
Cadeia de middleware
Linguagem
JavaScript / TypeScript
Versão
5.x

Por que importa

Por que o Express ainda está em todo lugar

Roteamento sem burocracia

Defina endpoints com app.get, app.post e similares. Caminhos podem ser estáticos, parametrizados ou baseados em padrões, e os handlers continuam sendo funções simples.

Middleware para tudo

Autenticação, logging, parsing e validação são apenas funções em uma cadeia. Componha pequenas peças em vez de configurar um framework robusto.

Um ecossistema enorme

Milhares de pacotes de middleware e anos de discussões significam que quase qualquer problema já possui uma solução pequena e bem testada.

O panorama completo

As três ideias por trás do Express

Uma rota corresponde a uma URL, um handler recebe a requisição e a resposta, e o middleware envolve tudo entre eles.

Roteamento

Corresponder

Um método e um caminho selecionam o handler que será executado. Rotas podem ser agrupadas em routers e montadas sob um prefixo.

Middleware

Compor

Funções recebem (req, res, next) e ou encerram a resposta ou passam o controle adiante na cadeia.

Requisição & Resposta

Troca

Wrappers leves sobre os objetos HTTP do Node — leia a entrada, defina status e headers, e envie o corpo da resposta.

HTML5 de uma olhada

O que você realmente recebe

Rotas

app.get("/posts/:id") corresponde a uma URL e executa um handler.

Middleware

app.use(fn) executa antes ou depois das rotas, na ordem de registro.

req e res

Leia params, query e body; defina o status e envie JSON ou arquivos.

Routers

express.Router() mantém apps grandes modulares e montáveis.

Middleware de erro

Uma função de quatro argumentos centraliza as respostas de erro.

Middleware de segurança

helmet, cors e rate limits são adicionados com apenas uma linha de código.

Uma breve historia

De um brinquedo inspirado no Sinatra a um padrão web

  1. 2010

    O Express nasce

    TJ Holowaychuk lança um pequeno framework inspirado no Sinatra do Ruby.

    10
  2. 2011

    Middleware do Connect

    O Express absorve o modelo de middleware do Connect, que define sua API por anos.

    11
  3. 2014

    Express 4

    O router é reescrito e o middleware é desmembrado em pacotes separados.

    14
  4. 2016

    A era da governança aberta

    A gestão da IBM e StrongLoop mantém o Express atualizado enquanto o Node cresce.

    16
  5. 2024

    Express 5

    Um lançamento major aguardado há muito tempo traz tratamento de erros assíncronos e uma base moderna.

    24

O guia completo

Express: Tudo que voce precisa saber

O que é Express?

Express é um framework web minimalista para Node.js. Ele não impõe a estrutura de pastas, o banco de dados ou a arquitetura do seu projeto. Ele oferece três coisas e deixa você trabalhar: uma forma de fazer o match de URLs, um objeto de requisição (request) e resposta (response), e uma cadeia de middleware que conecta tudo.

Essa simplicidade é proposital. O Express surgiu em 2010, quando o módulo http nativo do Node exigia que você escrevesse o roteamento e o parsing do corpo da requisição manualmente. Ele reduziu essas tarefas a poucas linhas. Quinze anos depois, ele continua sendo a escolha padrão para APIs em Node, e seus conceitos foram copiados por quase todos os frameworks que vieram a seguir.

Se você entende Express, você entende a estrutura do JavaScript no lado do servidor.

O ciclo de requisição e resposta

Em sua essência, um app Express é uma função que recebe uma requisição e envia uma resposta. Todo o restante são conveniências implementadas sobre isso.

import express from "express";

const app = express();

app.get("/", (req, res) => {
  res.send("Hello, world");
});

O objeto req encapsula a mensagem de entrada do Node.js: req.params, req.query, req.body e req.headers fornecem a entrada. O objeto res encapsula a mensagem de saída: res.status(), res.json(), res.send() e res.set() moldam a saída. Um handler encerra a requisição chamando um dos métodos res.

Roteamento

Uma rota é composta por um método, um caminho e um ou mais handlers. Os caminhos podem ser estáticos, parametrizados com :name ou correspondidos via padrões.

app.get("/posts", listPosts);
app.get("/posts/:id", getPost);
app.post("/posts", createPost);
app.put("/posts/:id", replacePost);
app.patch("/posts/:id", updatePost);
app.delete("/posts/:id", deletePost);

Os parâmetros de rota chegam em req.params, e as query strings em req.query.

app.get("/posts/:id", (req, res) => {
  const { id } = req.params;          // "/posts/42" -> "42"
  const { fields } = req.query;       // "?fields=title" -> "title"
  res.json({ id, fields });
});

Você também pode passar vários handlers para uma única rota. Eles são executados em ordem até que um deles finalize a resposta; é assim que você anexa middleware por rota, como validação ou autorização.

app.post("/posts", requireAuth, validatePost, createPost);

Middleware: a ideia fundamental para dominar

O middleware é o coração do Express. Ele é qualquer função que recebe (req, res, next) e, ou encerra a resposta, ou chama next() para continuar.

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

app.use(logger);

O middleware é executado na ordem em que é registrado. Essa única regra explica a maior parte do comportamento do Express: registre o parser de JSON antes das rotas que leem req.body, registre a autenticação antes das rotas protegidas e registre o handler de 404 depois de todas as rotas.

Existem três tipos que valem a pena conhecer:

  • Application middlewareapp.use(fn) é executado para cada requisição.
  • Router middlewarerouter.use(fn) é executado apenas para os caminhos daquele router.
  • Route middlewareapp.get(path, fn, handler) é executado apenas para aquela rota.

Um middleware que recebe quatro argumentos é um error handler e só é executado quando algo chama next(err).

Routers mantêm apps grandes legíveis

À medida que um app cresce, um único arquivo de rotas torna-se impossível de gerenciar. express.Router() permite que você agrupe rotas relacionadas e as monte sob um prefixo.

// routes/posts.js
import { Router } from "express";

const router = Router();

router.get("/", listPosts);
router.post("/", createPost);

export default router;
// app.js
import posts from "./routes/posts.js";

app.use("/api/v1/posts", posts);

Agora, cada arquivo é dono de um recurso, e o prefixo da URL fica em um único lugar. Essa é a estrutura que impede que projetos Express se transformem em um amontoado de endpoints.

Tratamento de erros

Os erros devem fluir para um único lugar. Chame next(err) de qualquer lugar e o Express saltará diretamente para o primeiro manipulador de erros de quatro argumentos.

app.get("/users/:id", async (req, res, next) => {
  try {
    const user = await db.user.findById(req.params.id);
    if (!user) return res.status(404).json({ error: "not_found" });
    res.json(user);
  } catch (err) {
    next(err);
  }
});
app.use((err, req, res, next) => {
  console.error(err);
  res.status(err.status ?? 500).json({
    error: err.code ?? "internal_error",
    message: err.message,
  });
});

O Express 5 encaminha promises rejeitadas para o manipulador de erros automaticamente, portanto, handlers async não precisam mais de um wrapper. Ainda assim, ser explícito com try/catch torna a intenção óbvia e mantém o código portátil. Registre um manipulador de 404 após todas as rotas para que caminhos não correspondidos retornem um erro JSON adequado em vez da página HTML padrão do Express.

Lendo o corpo da requisição

O Express não faz o parse de corpos por padrão. Adicione os parsers integrados antes das rotas que precisarem deles.

app.use(express.json());                        // application/json
app.use(express.urlencoded({ extended: true })); // form posts

Para upload de arquivos, utilize o multer. Para uma validação mais robusta, combine o parsing com uma biblioteca de schema como Zod ou Joi e rejeite entradas inválidas precocemente, antes que cheguem aos seus handlers.

Noções básicas de segurança e produção

O Express é deliberadamente minimalista, portanto, algumas linhas de middleware resolvem o essencial:

import helmet from "helmet";
import cors from "cors";
import rateLimit from "express-rate-limit";

app.use(helmet());                 // sensible security headers
app.use(cors({ origin: "https://app.example.com" }));
app.use(rateLimit({ windowMs: 60_000, max: 100 }));

Além disso, desative o x-powered-by, mantenha as dependências atualizadas, valide e limite o tamanho das requisições e nunca confie na entrada do cliente. Essas são as mesmas preocupações de qualquer backend; o Express apenas oferece um lugar pequeno e bem conhecido para lidar com cada uma delas.

Testes

Como os handlers são funções simples, o Express é fácil de testar. supertest inicia o app no mesmo processo e faz asserções HTTP reais sem a necessidade de abrir uma porta.

import request from "supertest";
import app from "../app.js";

test("GET /posts returns a list", async () => {
  const res = await request(app).get("/posts").expect(200);
  expect(Array.isArray(res.body)).toBe(true);
});

Separe a definição do app (app.js) da inicialização do servidor (server.js) para que os testes possam importar o app sem que ele fique escutando requisições. Essa simples separação torna os testes de integração triviais.

Melhores práticas

  • Mantenha os route handlers enxutos; mova a lógica para services e camadas de acesso a dados.
  • Divida as rotas por funcionalidade com express.Router() e monte-as sob um prefixo de versão.
  • Registre o middleware de forma deliberada e na ordem correta: parsers, depois auth, depois rotas, depois 404 e, por fim, erros.
  • Encaminhe cada erro com next(err) e formate as respostas em um único lugar.
  • Valide e limite todas as entradas antes que elas cheguem à lógica de negócio.
  • Use helmet, cors e rate limiting desde o primeiro dia.
  • Separe a aplicação do servidor para que os testes permaneçam rápidos.

Erros comuns

  • Esquecer o express.json() e se perguntar por que o req.body está undefined.
  • Ignorar promises rejeitadas em handlers assíncronos no Express 4.
  • Registrar o handler de 404 ou de erro antes das rotas que ele deveria capturar.
  • Deixar um único arquivo de rotas crescer por centenas de linhas.
  • Retornar 200 para erros em vez de utilizar status codes.
  • Confiar no req.body sem validação.
  • Misturar res.send, res.json e res.end de forma imprevisível.

Próximos passos

O Express ensina sobre a requisição, a resposta e a cadeia de middleware — conceitos que você reutilizará para sempre. Se você busca mais performance e validação nativa, leia o guia do Fastify a seguir. Se precisa de estrutura e injeção de dependência para equipes grandes, migre para o NestJS. Para implantações em edge e serverless, o Hono oferece o mesmo estilo em um runtime baseado em padrões web. E se tudo isso pareceu rápido demais, revise os fundamentos de Node.js que sustentam tudo isso.

Na pratica

Um app, quatro partes móveis

Alterne entre as peças para ver como elas se encaixam.

server.js
import express from "express";
import routes from "./routes.js";

const app = express();

app.use(express.json());
app.use("/api", routes);

app.listen(3000, () => console.log("http://localhost:3000"));

Tratando erros assíncronos

O Express 5 encaminha promises rejeitadas automaticamente, mas ser explícito ainda é mais claro e funciona da mesma forma em qualquer versão.

Preferível
router.get("/posts", async (req, res, next) => {
  try {
    const posts = await Post.find();
    res.json(posts);
  } catch (err) {
    next(err);
  }
});
Evite
router.get("/posts", async (req, res) => {
  const posts = await Post.find();
  res.json(posts);
  // rejection is silently lost in Express 4
});

Ordenação de middleware

O middleware executa na ordem de registro, portanto, o parser e a autenticação devem ser montados antes das rotas que dependem deles.

Preferível
app.use(express.json());
app.use(auth);
app.use("/api", routes);
app.use(notFound);
app.use(onError);
Evite
app.use("/api", routes);
app.use(express.json());
app.use(auth);
// body is undefined inside routes

Trade-offs

O Express é a escolha padrão correta?

O Express prioriza a familiaridade e a simplicidade. Conheça o custo antes de escalá-lo.

Strengths

  • Nada para aprender primeiro

    A API é minúscula, a documentação é excelente e quase todo desenvolvedor Node consegue ler um app Express no primeiro dia.

  • Ecossistema incomparável

    Autenticação, uploads, sessões, validação e logging possuem middlewares maduros com anos de uso em produção.

  • Você mantém o controle

    Não há estrutura oculta. Você escolhe a organização das pastas, o banco de dados e os padrões, em vez de adotar as opiniões de um framework.

Trade-offs

  • Você cria as convenções

    Sem uma estrutura acordada, apps Express grandes tendem a ter handlers inconsistentes. Um layout claro importa mais aqui do que em frameworks opinativos.

  • Performance é boa, mas não excelente

    O Express é rápido o suficiente para a maioria dos serviços, mas Fastify e Node puro conseguem lidar com significativamente mais requisições por segundo.

  • Erros assíncronos são fáceis de ignorar

    No Express 4, uma promise rejeitada é descartada silenciosamente. Mesmo no 5, um try/catch ou next(err) mantém as falhas visíveis.

Perguntas frequentes

Perguntas frequentes

Keep learning

Related topics from the roadmap.

$ comecar a aprender

Pronto para aprender Express?

Nosso tutorial interativo te guia por Express passo a passo — com quizzes e codigo real que voce pode executar no navegador.