Back to Next.js tutorials
Intermediate13 min read

Route Handlers

Build HTTP endpoints in the App Router for APIs, webhooks, and integrations.

When To Use Route Handlers

Route Handlers (`route.ts`) export HTTP method functions — GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS. Use for REST APIs consumed by external clients, mobile apps, webhooks from Stripe/GitHub, and OAuth callbacks.

Prefer Server Actions for form mutations from your own UI. Route Handlers when you need standard HTTP semantics, third-party integration, or non-HTML responses.

  • route.ts exports HTTP methods
  • Webhooks and external API consumers
  • Server Actions for own-UI mutations
export async function GET(request: Request) {
  const data = await fetchData();
  return Response.json(data);
}

Request and Response APIs

Handlers receive Web standard Request objects. Parse JSON with `await request.json()`, form data with `request.formData()`, query params from `new URL(request.url).searchParams`.

Return Response.json(), new Response(text), or NextResponse with cookies and headers. NextResponse.redirect() for OAuth flows. Set status codes explicitly for error responses.

  • Web standard Request/Response
  • NextResponse for cookies and redirects
  • Explicit status codes on errors

Authentication and Middleware

Validate session tokens or API keys at the start of handlers. Share auth utilities between Server Actions and Route Handlers. Middleware can pre-filter requests before handlers run for common auth patterns.

Webhook handlers verify signatures (Stripe signing secret, GitHub HMAC) before processing payloads — reject unsigned requests immediately.

  • Shared auth utilities
  • Verify webhook signatures
  • Middleware for common gatekeeping

Caching Route Handler Responses

GET handlers can export `export const revalidate = 60` or set Cache-Control headers on Response. Dynamic handlers serving user-specific data use `export const dynamic = 'force-dynamic'`.

Public read-heavy endpoints benefit from CDN caching with appropriate headers. User-specific endpoints must never cache shared responses.

  • revalidate export for ISR-style GET
  • Cache-Control headers for CDN
  • force-dynamic for user-specific data

Testing and Documentation

Test handlers by calling exported functions directly with mocked Request objects, or via integration tests hitting localhost. Document endpoints with OpenAPI specs generated from Zod schemas.

Version public APIs in path (`/api/v1/users`) from day one — breaking changes require new versions without disrupting existing integrations.

  • Direct function testing with mock Request
  • OpenAPI from Zod schemas
  • Version public APIs from start

Get In Touch


Ready to discuss your next project? Drop me a message.