On this page
API Routes and Route Handlers
Next.js lets you create API endpoints inside your project using Route Handlers. They live alongside your pages in the app/ directory.
Creating a Route Handler
A route.ts file exports HTTP method functions:
app/api/hello/route.ts → GET /api/hello
// app/api/hello/route.ts
import { NextResponse } from 'next/server';
export async function GET() {
return NextResponse.json({ message: 'Hello from Next.js API!' });
}
Supported HTTP Methods
Export named functions for each method:
// app/api/items/route.ts
import { NextRequest, NextResponse } from 'next/server';
export async function GET() {
const items = await db.item.findMany();
return NextResponse.json(items);
}
export async function POST(request: NextRequest) {
const body = await request.json();
const item = await db.item.create({ data: body });
return NextResponse.json(item, { status: 201 });
}
Supported exports: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS.
Dynamic Route Handlers
app/api/users/[id]/route.ts → /api/users/42
import { NextRequest, NextResponse } from 'next/server';
export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
const { id } = await params;
const user = await db.user.findUnique({ where: { id } });
if (!user) {
return NextResponse.json({ error: 'Not found' }, { status: 404 });
}
return NextResponse.json(user);
}
export async function DELETE(
request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
const { id } = await params;
await db.user.delete({ where: { id } });
return new NextResponse(null, { status: 204 });
}
Reading Request Data
export async function POST(request: NextRequest) {
const body = await request.json(); // JSON body
const query = request.nextUrl.searchParams.get('q'); // ?q=hello
const authHeader = request.headers.get('authorization'); // Headers
const name = (await request.formData()).get('name'); // Form data
return NextResponse.json({ received: body });
}
Response Helpers
return NextResponse.json({ data: 'value' });
return NextResponse.json({ error: 'Bad request' }, { status: 400 });
return NextResponse.redirect(new URL('/login', request.url));
const response = NextResponse.json({ success: true });
response.cookies.set('token', 'abc123', { httpOnly: true });
return response;
Route Handlers vs Server Actions
| Route Handlers | Server Actions |
|---|---|
| REST API endpoints | Form mutations |
| Called by external clients | Called from your UI |
| Webhooks, mobile apps | Create, update, delete forms |
Use Route Handlers when you need a public API. Use Server Actions for form submissions within your app.
Edge Runtime
Run handlers on the Edge for lower latency:
export const runtime = 'edge';
export async function GET() {
return NextResponse.json({ region: process.env.VERCEL_REGION });
}
Next: intercept requests with middleware for auth and redirects.