API Routes no Next.js: como criar endpoints do zero
Índice
ToggleSe você trabalha ou está começando com Next.js, em algum momento vai precisar que sua aplicação converse com algum banco de dados, consuma um serviço externo ou devolva dados em formato JSON para o front-end. É exatamente para isso que existem as API Routes: pequenos blocos de código que rodam no servidor e respondem a requisições HTTP, tudo dentro do mesmo projeto em que você já está desenvolvendo as páginas.
A grande vantagem é que você não precisa levantar um servidor Express, configurar rotas em outro projeto nem se preocupar com CORS (mecanismo de segurança que controla quais sites podem chamar sua API) em vários cenários. Com Next.js, você cria um arquivo, exporta uma função e pronto: já tem um endpoint funcionando.
Neste guia, você vai entender o que são API Routes, como o mecanismo de roteamento do Next.js lida com elas, quais métodos HTTP você pode usar e como criar sua primeira rota tanto em JavaScript quanto em TypeScript. Também vamos falar sobre boas práticas, limitações e quando vale a pena considerar outras alternativas.
O que são API Routes no Next.js

API Routes é o recurso do framework Next.js que transforma arquivos dentro da pasta pages/api (no Pages Router, o roteador tradicional do Next.js) ou arquivos route.ts (no App Router, o roteador mais novo baseado em React Server Components) em endpoints HTTP prontos para receber requisições. Cada arquivo vira uma URL e exporta uma função que recebe a requisição e devolve a resposta.
A ideia central é simples: em vez de ter um backend separado, você usa o próprio servidor do Next.js para responder chamadas de API. Isso facilita a vida em projetos menores, MVPs (produto mínimo viável, a versão mais simples de um produto para validar uma ideia) ou quando a lógica de backend é simples o suficiente para caber junto com o front-end.
Como o Next.js cuida do roteamento e do servidor de arquivos estáticos, as API Routes herdam essa mesma filosofia de "convenção sobre configuração": você segue um padrão de pastas e nomes, e o framework faz o resto.
Como o Next.js roteia as requisições
Quando alguém acessa https://seusite.com/api/usuarios, o Next.js procura dentro de pages/api/usuarios.js (ou app/api/usuarios/route.ts, dependendo do roteador) e executa a função exportada. Você não precisa registrar nada em lugar nenhum, basta o arquivo existir.
Esse mesmo mecanismo funciona para arquivos dinâmicos, como [id].js ou [slug].ts, que capturam partes da URL e tornam acessíveis dentro da função. Por exemplo, uma rota em pages/api/produtos/[id].js aceita URLs como /api/produtos/42.
Por que usar API Routes em vez de um backend separado
Há cenários em que essa abordagem brilha:
- Projetos pequenos e médios em que manter dois códigos separados aumenta a complexidade sem ganho real.
- Endpoints usados exclusivamente pelo front-end do mesmo projeto.
- como rotas de autenticação internas.
- webhooks de provedores de pagamento ou proxies que escondem chaves de API.
- Protótipos e provas de conceito em que velocidade de entrega importa mais do que escalabilidade extrema.
Por outro lado, quando sua aplicação começa a crescer em complexidade, com integrações múltiplas, regras de negócio pesadas ou necessidade de fila e processamento assíncrono, um backend dedicado em Node.js, NestJS, Python ou outra linguagem costuma ser a melhor escolha.
Diferença entre Pages Router e App Router
É importante entender que existem dois sistemas de roteamento principais no Next.js, e cada um trata as API Routes de um jeito diferente. Pages Router: usa a pasta pages/api/ e arquivos que exportam funções nomeadas como default, recebendo os objetos req (requisição) e res (resposta) do Node.js. App Router: usa a pasta app/api/ e arquivos route.ts (ou route.js) que exportam funções nomeadas pelos métodos HTTP, como GET, POST, PUT, DELETE.
A partir do Next.js 13, o App Router se tornou o padrão recomendado, mas o Pages Router continua funcionando e tem bastante conteúdo na web. Vamos ver como criar sua primeira rota nos dois modelos.
Criando sua primeira API Route no Pages Router

Vamos começar pelo Pages Router por ser mais simples e didático. A lógica é basicamente: criar um arquivo, exportar uma função e devolver uma resposta.
Estrutura básica de uma rota
Imagine que você quer criar um endpoint que devolve uma lista de usuários em JSON. O arquivo ficaria assim, salvo como pages/api/usuarios.js:
export default function handler(req, res) {
const usuarios = [
{ id: 1, nome: "Ana" },
{ id: 2, nome: "Bruno" }
];
res.status(200).json(usuarios);
}
Pronto. Ao acessar /api/usuarios, você recebe um JSON com a lista. O objeto req traz informações da requisição (método, cabeçalhos, corpo, parâmetros de URL), e o res é o que você usa para devolver a resposta, definindo o status HTTP e os dados retornados.
Lidando com métodos HTTP diferentes
Em uma API real, você raramente quer que o mesmo endpoint aceite qualquer método sem tratamento. O mais comum é filtrar por método:
export default function handler(req, res) {
if (req.method === "GET") {
return res.status(200).json({ mensagem: "Lista de usuários" });
}
if (req.method === "POST") {
const { nome, email } = req.body;
return res.status(201).json({ id: 3, nome, email });
}
res.setHeader("Allow", "GET, POST");
return res.status(405).json({ erro: "Método não permitido" });
}
Note o status 405 (Method Not Allowed), que é o código HTTP correto para indicar que o método existe no servidor, mas não é aceito naquele recurso. Também definimos o cabeçalho Allow para informar quais métodos são válidos.
Rotas dinâmicas
Se você precisa tratar, por exemplo, a busca de um produto pelo identificador, usa arquivos com colchetes no nome. Crie pages/api/produtos/[id].js:
export default function handler(req, res) {
const { id } = req.query;
res.status(200).json({
id,
nome: `Produto ${id}`,
preco: 99.9
});
}
Agora GET /api/produtos/10 devolve os dados do produto com identificador 10.
Middleware e helpers comuns
Algumas bibliotecas foram pensadas para facilitar a vida com API Routes, especialmente a integração com o Parse Server. As mais conhecidas:
- next-connect: permite organizar handlers (funções intermediárias que processam requisições antes de chegar ao destino) por método HTTP de forma mais limpa.
- cors: configura cabeçalhos de CORS quando sua API é chamada por outros domínios.
- helmet: adiciona cabeçalhos de segurança automáticos.
Um exemplo com next-connect:
import nc from "next-connect";
import cors from "cors";
const handler = nc();
handler.use(cors()).get((req, res) => {
res.status(200).json({ ok: true });
});
export default handler;
Esse padrão ajuda a manter o arquivo organizado quando você tem vários métodos e middlewares.
Criando API Routes no App Router

O App Router é o modelo recomendado a partir do Next.js 13 e usa uma abordagem diferente, baseada em convenções do React Server Components.
Estrutura básica com route.ts
Para criar o equivalente da rota /api/usuarios que vimos antes, você cria o arquivo app/api/usuarios/route.ts (ou route.js, se estiver usando JavaScript puro):
import { NextResponse } from "next/server";
export async function GET() {
const usuarios = [
{ id: 1, nome: "Ana" },
{ id: 2, nome: "Bruno" }
];
return NextResponse.json(usuarios);
}
Perceba que cada método HTTP vira uma função nomeada, e o retorno é direto, sem precisar manipular req e res. Essa abordagem é mais declarativa e fica fácil de ler.
Aceitando requisições POST
Para criar um produto novo a partir de um JSON enviado no corpo da requisição:
import { NextResponse } from "next/server";
export async function POST(request: Request) {
const corpo = await request.json();
const { nome, preco } = corpo;
if (!nome || !preco) {
return NextResponse.json(
{ erro: "Nome e preço são obrigatórios" },
{ status: 400 }
);
}
return NextResponse.json(
{ id: 10, nome, preco },
{ status: 201 }
);
}
Aqui usamos o objeto Request padrão da Fetch API (a interface moderna do navegador para requisições HTTP, também disponível no servidor) e NextResponse.json para devolver a resposta.
Rotas dinâmicas no App Router
O princípio é o mesmo, mas os colchetes ficam no nome da pasta. Estrutura app/api/produtos/[id]/route.ts:
export async function GET(
request: Request,
{ params }: { params: { id: string } }
) {
return Response.json({
id: params.id,
nome: `Produto ${params.id}`,
preco: 99.9
});
}
Agora GET /api/produtos/10 devolve os dados do produto com identificador 10.
Middleware nativo do Next.js
Para interceptar requisições antes que cheguem às rotas, o Next.js oferece o arquivo middleware.ts na raiz do projeto. Ele é útil para checagem de autenticação, redirecionamentos e cabeçalhos globais.
Exemplo simples:
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(request: NextRequest) {
const token = request.cookies.get("token");
if (!token && request.nextUrl.pathname.startsWith("/api/")) {
return NextResponse.json(
{ erro: "Não autorizado" },
{ status: 401 }
);
}
return NextResponse.next();
}
export const config = {
matcher: ["/api/:path*"]
};
Esse middleware bloqueia qualquer chamada a /api/* quando não existe o cookie token, devolvendo 401 (Não Autorizado). É um ótimo ponto de partida para proteção de rotas internas.
Métodos HTTP suportados e como usá-los

Independentemente do roteador escolhido, o conjunto de métodos HTTP disponíveis para API Routes é o mesmo, e cada um tem um papel claro na construção da API. Os mais comuns são:
- GET: buscar dados (idempotente.
- ou seja.
- executa várias vezes produzindo o mesmo resultado).
- POST: criar um recurso novo.
- PUT: substituir um recurso existente por completo.
- PATCH: atualizar parcialmente um recurso.
- DELETE: remover um recurso.
- OPTIONS: usado pelo navegador para checar permissões de CORS antes de uma requisição real.
A tabela a seguir resume o uso e os status HTTP esperados em cada caso.
| Método | Uso comum | Status de sucesso | Status de erro típico |
|---|---|---|---|
| GET | Ler dados | 200 | 404 |
| POST | Criar recurso | 201 | 400, 409 |
| PUT | Substituir recurso | 200 ou 204 | 400, 404 |
| PATCH | Atualização parcial | 200 | 400, 404 |
| DELETE | Remover recurso | 204 | 404 |
| OPTIONS | Pré-voo de CORS | 204 | 405 |
Dominar esse vocabulário ajuda a construir APIs previsíveis e fáceis de consumir por outros sistemas.
Boas práticas para API Routes
Criar uma rota que funciona é fácil. Criar uma rota que funciona bem em produção exige atenção a alguns detalhes.
Valide entradas
Nunca confie no que chega pela requisição. Use uma biblioteca como Zod, Yup ou Valibot para validar o corpo (body), os parâmetros de URL (query) e os cabeçalhos. Isso evita que dados malformados cheguem ao seu banco e quebrem a aplicação.
Exemplo com Zod:
import { z } from "zod";
const schema = z.object({
nome: z.string().min(2),
email: z.string().email()
});
export async function POST(request: Request) {
const dados = schema.safeParse(await request.json());
if (!dados.success) {
return Response.json(
{ erro: "Dados inválidos", detalhes: dados.error.flatten() },
{ status: 400 }
);
}
return Response.json({ id: 1...dados.data }, { status: 201 });
}
Padronize as respostas de erro
Defina um formato único para erros e use-o em todas as rotas. Por exemplo:
{
"erro": "Mensagem amigável",
"codigo": "USUARIO_NAO_ENCONTRADO",
"detalhes": {}
}
Isso facilita a vida de quem consome a API e simplifica a implementação de logs (registros de eventos) e monitoramento.
Não exponha segredos
Variáveis de ambiente com prefixo NEXT_PUBLIC_ ficam disponíveis no front-end. Para segredos como chaves de banco e tokens de integração, use o prefixo padrão (sem NEXT_PUBLIC_) e mantenha o acesso restrito às API Routes e a outros arquivos de servidor.
Limite tamanho do corpo
Requisições muito grandes podem causar lentidão ou até negação de serviço (ataques em que o invasor sobrecarrega o servidor enviando requisições enormes ou em grande volume). O Next.js aplica limites por padrão, mas vale revisar a documentação ao trabalhar com upload de arquivos ou JSONs pesados.
Use cache quando fizer sentido
Para endpoints que devolvem dados que mudam pouco, é possível usar o cabeçalho Cache-Control ou revalidar rotas com revalidatePath no App Router. Isso reduz a carga no banco e melhora a experiência do usuário.
Exemplos práticos para o dia a dia
A teoria ajuda, mas o que fixa o conteúdo são exemplos reais. Vamos ver três situações comuns que aparecem em praticamente qualquer projeto.
Exemplo 1: endpoint de contato
Recebe dados de um formulário enviado pelo front-end, valida o conteúdo e devolve confirmação.
export async function POST(request: Request) {
const { nome, email, mensagem } = await request.json();
if (!nome || !email || !mensagem) {
return Response.json(
{ erro: "Preencha todos os campos" },
{ status: 400 }
);
}
// Aqui entra o envio de e-mail ou persistência em banco
console.log("Novo contato", { nome, email, mensagem });
return Response.json({ ok: true }, { status: 201 });
}
Salvar como app/api/contato/route.ts.
Exemplo 2: proxy para API externa
Às vezes você quer esconder a chave de API de um serviço externo ou aplicar regras próprias antes de responder ao front-end. Crie um proxy (intermediário que repassa e adapta requisições) no Next.js que recebe a chamada, adiciona a chave e repassa.
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const cidade = searchParams.get("cidade");
const resposta = await fetch(
`https://api.exemplo.com/clima?cidade=${cidade}&key=${process.env.CHAVE_API}`
);
const dados = await resposta.json();
return Response.json(dados);
}
A chave nunca é exposta ao navegador porque só roda no servidor.
Exemplo 3: integração com banco de dados
Conectando a um banco PostgreSQL usando o Prisma:
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
export async function GET() {
const usuarios = await prisma.usuario.findMany();
return Response.json(usuarios);
}
Em produção, vale criar uma única instância do Prisma para evitar reabrir conexão a cada requisição. O Next.js oferece um padrão recomendado para isso chamado "singleton" (instância única compartilhada).
Limitações e quando considerar alternativas
API Routes resolvem bem a maioria dos casos comuns, mas é justo listar onde elas começam a engessar. Funções serverless (executadas sob demanda em plataformas de nuvem, em vez de em servidores fixos) têm tempo limite de execução. Na Vercel, o limite padrão para planos gratuitos é 10 segundos no plano Hobby e 60 segundos no plano Pro para API Routes no Pages Router. Para o App Router, os limites são parecidos. Tarefas longas precisam rodar fora. Em plataformas como Vercel, Cold Start (primeira execução após período ocioso) pode adicionar latência nas primeiras requisições após muito tempo sem uso. Streaming de respostas (envio de dados em pedaços, em vez de tudo de uma vez) é mais limitado do que em servidores Express ou Fastify. Para envio de dados em tempo real ou downloads longos, considere outras soluções. Tarefas pesadas com uso intenso de CPU podem exigir ajuste de plano ou mudança para uma plataforma com runtime (ambiente de execução) mais robusto.
Se você esbarrar nesses limites, opções a considerar incluem Express, Fastify, NestJS, Hono, ou mesmo workers em Python, Ruby ou Go, integrados via API separada.
Como testar API Routes
Testar é parte essencial do trabalho. Existem três camadas principais que você pode usar.
Testes manuais com curl ou ferramentas visuais
Para checagens rápidas, basta usar curl no terminal ou ferramentas como Postman e Insomnia. Exemplo:
curl http://localhost:3000/api/usuarios
Testes automatizados com Jest e Supertest
Para projetos maiores, vale criar testes que simulam requisições. Bibliotecas como Jest, Vitest, Supertest ou node-mock-http facilitam isso.
Logs estruturados
Adicionar logs (registros de eventos do sistema) em pontos-chave da rota ajuda a investigar bugs. Bibliotecas como pino e winston produzem logs estruturados em JSON, fáceis de enviar para serviços como Datadog ou Sentry.
Perguntas Frequentes (FAQ)
API Routes substituem um backend tradicional?
Elas substituem em projetos pequenos e médios, onde a maioria das chamadas é feita pelo próprio front-end do Next.js. Para sistemas com regras de negócio complexas, integrações com vários sistemas ou necessidade de filas e processamento assíncrono, um backend dedicado ainda é a melhor escolha.
Qual a diferença entre Pages Router e App Router para API Routes?
No Pages Router, você cria arquivos em pages/api/ que exportam uma função padrão recebendo req e res. No App Router, você cria arquivos route.ts em app/api/ que exportam funções nomeadas pelo método HTTP, como GET e POST, retornando objetos Response ou NextResponse.
Posso usar TypeScript nas API Routes?
Sim. Tanto no Pages Router quanto no App Router, basta criar arquivos com extensão .ts ou .tsx e configurar o tsconfig.json. No App Router, a tipagem dos parâmetros e do retorno tende a ser mais ergonômica por usar os padrões da Web, como Request e Response.
Como proteger API Routes contra acessos não autorizados?
As opções mais comuns incluem checar tokens JWT (token assinado que carrega informações de autenticação) ou de sessão no cabeçalho da requisição, validar a origem via cabeçalhos CORS, usar o middleware.ts para bloquear rotas e aplicar rate limit (limite de requisições por intervalo de tempo) via bibliotecas como Upstash Ratelimit.
Existe limite de tamanho para o corpo da requisição?
Sim. Por padrão, o Next.js aplica limites razoáveis para evitar abuse. Para upload de arquivos grandes, é comum configurar tamanho específico ou enviar o arquivo diretamente para um serviço de storage como S3, Cloudflare R2 ou Supabase Storage, recebendo apenas a URL no corpo da requisição.
Conclusão
API Routes são um dos recursos mais democráticos do Next.js. Com pouco código, você coloca um endpoint no ar, recebe dados, conecta a bancos e integra com serviços externos, tudo dentro do mesmo projeto em que está construindo as páginas. Para produtos digitais em validação, sites institucionais, MVPs e painéis administrativos internos, essa abordagem economiza tempo e reduz a superfície de manutenção.
Agora, vale destacar que, apesar da simplicidade aparente, existem decisões que pesam no resultado: escolher entre Pages Router e App Router, validar entradas, proteger rotas e estruturar respostas de erro são detalhes que evitam dor de cabeça quando o projeto cresce.
Se você precisa de ajuda para colocar isso em prática ou quer construir uma aplicação mais robusta usando Next.js, a Baita Site tem uma equipe especializada em sites, e-commerce, sistemas e inteligência artificial, com domínio total de WordPress e do ecossistema JavaScript moderno. Fale com a gente e veja como podemos acelerar o seu projeto.
Este conteúdo tem caráter informativo. Decisões técnicas devem ser tomadas com profissional especializado.
Referências consultadas, Documentação oficial do Next.js sobre API Routes no Pages Router
https://nextjs.org/docs/pages/building-your-application/routing/api-routes, Documentação oficial do Next.js sobre Route Handlers no App Router: https://nextjs.org/docs/app/building-your-application/routing/route-handlers, Documentação do Next.js sobre Middleware: https://nextjs.org/docs/app/building-your-application/routing/middleware, Repositório da biblioteca next-connect no GitHub: https://github.com/hoangvvo/next-connect, Artigo sobre boas práticas em APIs REST na documentação do MDN Web Docs: https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Methods
Quer ajuda para colocar isso em pratica?
A Baita Site trabalha com sites, e-commerce, sistemas e IA. Quem prefere resolver com acompanhamento, sem ter que virar especialista em tudo, costuma procurar esse tipo de suporte.
Veja tambem
Perguntas Frequentes (FAQ)
1. API Routes substituem um backend tradicional?
Elas substituem em projetos pequenos e médios, onde a maioria das chamadas é feitas pelo próprio front-end do Next.js. Para sistemas com regras de negócio complexas, várias integrações ou necessidade de filas e processamento assíncrono, um backend dedicado ainda é a melhor escolha.
2. Qual a diferença entre Pages Router e App Router para API Routes?
No Pages Router, você cria arquivos em pages/api/ que exportam uma função padrão recebendo req e res. No App Router, você cria arquivos route.ts em app/api/ que exportam funções nomeadas pelo método HTTP, como GET e POST, retornando objetos Response ou NextResponse.
3. Posso usar TypeScript nas API Routes?
Sim. Tanto no Pages Router quanto no App Router, basta criar arquivos com extensão .ts ou .tsx e configurar o tsconfig.json. No App Router, a tipagem tende a ser mais ergonômica por usar os padrões da Web, como Request e Response.
4. Como proteger API Routes contra acessos não autorizados?
As opções mais comuns incluem checar tokens JWT ou de sessão no cabeçalho da requisição, validar a origem via cabeçalhos CORS, usar o middleware.ts para bloquear rotas e aplicar rate limit por meio de bibliotecas como Upstash Ratelimit.
5. Existe limite de tamanho para o corpo da requisição?
Sim. Por padrão, o Next.js aplica limites razoáveis para evitar abuso. Para upload de arquivos grandes, é comum configurar tamanho específico ou enviar o arquivo diretamente para um serviço de storage como S3, Cloudflare R2 ou Supabase Storage, recebendo apenas a URL no corpo da requisição.