Route Handlers — API Routes in app/

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.

4 min read Level 2/5 #nextjs#route-handlers#api
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.

redirect() & notFound() →