SkillByAIOpen interactive version →

Lesson 17 / 25

Route Handlers

HTTP endpoints in route.ts.

Export functions named after HTTP methods

A route.ts file exports functions named GET, POST, PUT, DELETE and so on, using the standard Web Request and Response APIs (with NextRequest for helpers such as parsed search params). Use Route Handlers for webhooks, public APIs, endpoints for mobile apps or other clients, and file downloads. For mutations triggered from your own React UI, Server Actions are often simpler. Validate input and return proper status codes.

The HTTP layer

Route Handlers build APIs, Proxy runs before requests, and config redirects move URLs.

Figure 6.1 — Route Handlers, Proxy and redirects.

A products API with GET and POST

This file is from a small demo store I built with Next.js 16.3.8, React 19.3 and TypeScript; next build compiled and type-checked it successfully. GET filters products by a q search parameter; POST validates the JSON body and returns 400 or 201.

import { NextRequest } from "next/server";
import { getProducts } from "@/lib/data";

export async function GET(request: NextRequest) {
  const q = request.nextUrl.searchParams.get("q")?.toLowerCase() ?? "";
  const products = (await getProducts()).filter((p) => p.name.toLowerCase().includes(q));
  return Response.json({ count: products.length, products });
}

export async function POST(request: Request) {
  const body = await request.json().catch(() => null);
  if (!body || typeof body.name !== "string" || typeof body.price !== "number") {
    return Response.json({ error: "name (string) and price (number) are required" }, { status: 400 });
  }
  return Response.json({ created: { id: "4", ...body } }, { status: 201 });
}

Calling the API, run

I built the demo store with next build (Next.js 16.3.8), started it with next start and requested pages with curl; the output is copied from that run, trimmed to the relevant lines. Searching for "pen" finds the fountain pen; a POST without a price returns 400; a complete body returns 201.

curl -s "http://localhost:3917/api/products?q=pen"
curl -s -X POST -H "content-type: application/json" -d '{"name":"Stapler"}' -w " status %{http_code}" http://localhost:3917/api/products
curl -s -X POST -H "content-type: application/json" -d '{"name":"Stapler","price":250}' -w " status %{http_code}" http://localhost:3917/api/products

Output:

{"count":1,"products":[{"id":"2","name":"Fountain pen","price":899}]}
{"error":"name (string) and price (number) are required"} status 400
{"created":{"id":"4","name":"Stapler","price":250}} status 201

Quick check: What does a Route Handler file export?

  • A CSS module
  • A React component named Page
  • Functions named after HTTP methods, such as GET and POST
  • A layout
Answer

Functions named after HTTP methods, such as GET and POST — route.ts is an HTTP endpoint.