Build API endpoints with route.ts files, handle GET/POST and JSON, read dynamic params, and opt into caching.
Why: a route.ts file is an API endpoint. Export a function named after the HTTP method (GET, POST, …) and return a Response. Use these for webhooks, third-party callbacks, or data for non-React clients. Note: a folder can have a page.tsx OR a route.ts, not both.
// app/api/hello/route.ts -> GET /api/hello
export async function GET() {
return Response.json({ message: 'Hello!' })
}Why: handlers receive the standard web Request, so you read query params, headers, and the body with normal web APIs. Return any HTTP method handler you need; an unsupported method automatically gets a 405.
// app/api/search/route.ts
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const q = searchParams.get('q') ?? ''
return Response.json({ query: q })
}
// POST with a JSON body
export async function POST(request: Request) {
const body = await request.json()
return Response.json({ received: body }, { status: 201 })
}Why: just like pages, [id] in the path becomes a param. The typed RouteContext helper gives you correct types for it without writing them yourself. Note: like page params, ctx.params is awaited.
// app/users/[id]/route.ts -> GET /users/123
import type { NextRequest } from 'next/server'
export async function GET(_req: NextRequest, ctx: RouteContext<'/users/[id]'>) {
const { id } = await ctx.params
return Response.json({ id })
}Why: handlers aren’t cached by default. With Cache Components enabled, a GET that only returns static data is pre-rendered automatically; to cache data that comes from a database, wrap that work in a helper marked "use cache".
// app/api/products/route.ts
import { cacheLife } from 'next/cache'
export async function GET() {
const products = await getProducts()
return Response.json(products)
}
// "use cache" can't sit directly in the handler — put it in a helper:
async function getProducts() {
'use cache'
cacheLife('hours')
return db.query('SELECT * FROM products')
}