← Back to chapters
10intermediate

API Routes (Route Handlers)

Build your backend inside Next.js. GET, POST, dynamic routes, and middleware.

Route Handlers: Your Backend in Next.js

Sometimes you need actual API endpoints, for webhooks, third-party integrations, or when you want a REST API. Route Handlers let you create API routes using the Web Request/Response APIs.

Basic Route Handler

src/app/api/hello/route.ts
tsx
1// src/app/api/hello/route.ts
2import { NextResponse } from "next/server";
3
4export async function GET() {
5return NextResponse.json({ message: "Hello from the API!" });
6}
7
8export async function POST(request: Request) {
9const body = await request.json();
10
11// Process the data...
12
13return NextResponse.json(
14 { success: true, data: body },
15 { status: 201 }
16);
17}

The file is called 'route.ts' (not page.ts). You export functions named after HTTP methods: GET, POST, PUT, PATCH, DELETE.

Dynamic API Routes

src/app/api/posts/[id]/route.ts
tsx
1// src/app/api/posts/[id]/route.ts
2import { NextResponse } from "next/server";
3
4export async function GET(
5request: Request,
6{ params }: { params: Promise<{ id: string }> }
7) {
8const { id } = await params;
9
10// Fetch from database
11const post = await getPost(id);
12
13if (!post) {
14 return NextResponse.json(
15 { error: "Post not found" },
16 { status: 404 }
17 );
18}
19
20return NextResponse.json(post);
21}
22
23export async function DELETE(
24request: Request,
25{ params }: { params: Promise<{ id: string }> }
26) {
27const { id } = await params;
28await deletePost(id);
29return new Response(null, { status: 204 });
30}
⚠️

Don't overuse API routes

If you're just fetching data for your own pages, use Server Components directly. If you're mutating data from forms, use Server Actions. API routes are best for:
• Webhooks
• Third-party integrations
• When you need a public REST API

Reading Headers, Cookies & Query Params

src/app/api/search/route.ts
tsx
1import { NextResponse } from "next/server";
2import { cookies, headers } from "next/headers";
3
4export async function GET(request: Request) {
5// Query params
6const { searchParams } = new URL(request.url);
7const query = searchParams.get("q");
8const page = searchParams.get("page") ?? "1";
9
10// Headers
11const headersList = await headers();
12const auth = headersList.get("authorization");
13
14// Cookies
15const cookieStore = await cookies();
16const token = cookieStore.get("session-token");
17
18return NextResponse.json({ query, page });
19}

Watch and Learn