Capítulo 16 de 456
Route Handlers criam handlers de request customizados por rota usando as Web APIs Request/Response, definidos em arquivos route.js|ts dentro de app. Equivalem às API Routes do pages, mas não devem ser usados junto delas na mesma rota.
route.js|ts: exporta funções nomeadas por método HTTP (GET, POST, etc.); pode aninhar em qualquer nível de app, mas não pode coexistir com page.js no mesmo segmento de rota.GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS; método não suportado retorna 405 Method Not Allowed.NextRequest/NextResponse: extensões do Request/Response nativos com helpers convenientes para casos avançados.GET pode optar por cache com export const dynamic = 'force-static'; outros métodos nunca são cacheados, mesmo no mesmo arquivo de um GET cacheado.GET Route Handlers seguem o mesmo modelo de prerender de rotas UI normais: rodam em request time por padrão, podem ser prerenderizados se não acessarem dado não cacheado/runtime, e podem usar use cache (extraído para uma função helper, não direto no corpo do handler) para incluir dado não cacheado na resposta estática.RouteContext): tipo global gerado automaticamente (via next dev/next build/next typegen) para tipar o parâmetro context de um Route Handler tipado por rota.export async function GET(request: Request) {}
app/api/route.ts.export const dynamic = 'force-static'
export async function GET() {
const res = await fetch('https://data.mongodb-api.com/...', {
headers: { 'Content-Type': 'application/json', 'API-Key': process.env.DATA_API_KEY },
})
const data = await res.json()
return Response.json({ data })
}
GET handler via route config option.import { cacheLife } from 'next/cache'
export async function GET() {
const products = await getProducts()
return Response.json(products)
}
async function getProducts() {
'use cache'
cacheLife('hours')
return await db.query('SELECT * FROM products')
}
use cache extraído para função helper permite que dado não cacheado (query de DB) entre na resposta prerenderizada.import type { NextRequest } from 'next/server'
export async function GET(_req: NextRequest, ctx: RouteContext<'/users/[id]'>) {
const { id } = await ctx.params
return Response.json({ id })
}
context com o helper global RouteContext para uma rota dinâmica.| Page | Route | Resultado |
|---|---|---|
app/page.js | app/route.js | Conflito |
app/page.js | app/api/route.js | Válido |
app/[user]/page.js | app/api/route.js | Válido |
route.js no mesmo segmento de um page.js: conflito, não permitido (cada segmento pertence a um ou outro).use cache diretamente no corpo do Route Handler: não suportado; extrair para uma função helper separada.POST/PUT/etc. sejam cacheados por estarem no mesmo arquivo de um GET com force-static: só GET pode ser cacheado; os demais métodos nunca são.app; não use os dois padrões juntos na mesma rota.GET pode ser cacheado, e só com opt-in explícito (force-static ou, com Cache Components, ausência de acesso a dado não cacheado/runtime).Math.random()/headers() vs. use cache) se aplica a GET handlers.RouteContext<'/path/[param]'> tipa context.params automaticamente a partir da rota, gerado por next dev/build/typegen.GET handlers sob Cache Components é literalmente o mesmo modelo descrito para páginas.sitemap.ts, opengraph-image.tsx, icon.tsx) seguem a mesma regra de estático-por-padrão salvo uso de API de request-time.