Route Handlers: Building API Endpoints in the Next.js App Router
Route Handlers are the App Router's version of API routes. A route.ts file exports functions named after HTTP methods and uses the standard Web Request and Response APIs.
GET and POST
// app/api/projects/route.ts
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const status = searchParams.get('status') ?? 'active';
const projects = await db.project.findMany({ where: { status } });
return NextResponse.json(projects);
}
export async function POST(request: Request) {
const body = await request.json();
if (!body?.name) return NextResponse.json({ error: 'name is required' }, { status: 422 });
const project = await db.project.create({ data: { name: body.name } });
return NextResponse.json(project, { status: 201 });
}
Dynamic segments
// app/api/projects/[id]/route.ts
export async function DELETE(_req: Request, { params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
await db.project.delete({ where: { id } });
return new Response(null, { status: 204 });
}
Webhooks: read the raw body
// app/api/webhooks/payments/route.ts
export async function POST(request: Request) {
const raw = await request.text(); // needed for signature checks
const signature = request.headers.get('x-signature');
if (!verifySignature(raw, signature)) return new Response('Invalid signature', { status: 400 });
await handleEvent(JSON.parse(raw));
return new Response('ok');
}
Route Handler or Server Action?
- Server Action - mutations triggered by your own UI (forms, buttons).
- Route Handler - endpoints called by others: webhooks, mobile apps, third parties, or anything that needs a stable public URL and custom HTTP semantics.
Authenticate inside every handler. A proxy.ts redirect does not protect API routes on its own.
Was this article helpful?
Comments
No comments yet. Have a question or a tip? Be the first to share it.