route.ts Exports GET, POST, PUT, DELETE
Route Handlers — API Routes in app/
A route.ts file in the App Router exports HTTP method handlers, giving you an API in the same directory tree as your UI.
What you'll learn
- Create `app/api/users/route.ts`
- Export `GET` and `POST` functions
- Return `Response` or `NextResponse`
A route.ts file is the API equivalent of page.tsx. Instead of exporting a
component, you export named functions for each HTTP method — and the segment becomes
an endpoint.
A Simple GET
// app/api/users/route.ts
export async function GET() {
const users = [
{ id: '1', name: 'Ada' },
{ id: '2', name: 'Linus' },
];
return Response.json(users);
} GET /api/users returns the JSON body. The Response and Request globals are the
standard web types — no special Next.js objects required.
POST with a Body
// app/api/users/route.ts
export async function POST(request: Request) {
const body = (await request.json()) as { name: string };
const created = await db.users.create({ data: body });
return Response.json(created, { status: 201 });
} You can export GET, POST, PUT, PATCH, DELETE, HEAD, and OPTIONS from the
same file. Methods you do not export return a 405.
Dynamic Route Handlers
Dynamic segments work the same as for pages — bracket folders, params as a Promise.
// app/api/users/[id]/route.ts
export async function GET(
_request: Request,
{ params }: { params: Promise<{ id: string }> },
) {
const { id } = await params;
const user = await db.users.findUnique({ where: { id } });
if (!user) return new Response('Not found', { status: 404 });
return Response.json(user);
} NextResponse for Extras
When you need to set cookies, redirect, or rewrite, reach for NextResponse from
next/server.
import { NextResponse } from 'next/server';
export async function POST() {
const res = NextResponse.json({ ok: true });
res.cookies.set('session', 'abc123', { httpOnly: true });
return res;
} The next lesson is about short-circuiting rendering from server code with redirect
and notFound.