Careeroza
Creating a Route Handler
route.ts
A route.ts file exports functions named after HTTP methods. It uses the Web Request and Response APIs. A folder cannot have both page.tsx and route.ts.
app/api/products/route.ts
import { prisma } from '@/lib/prisma';
export async function GET() {
const products = await prisma.product.findMany({ take: 20 });
return Response.json(products);
}
export async function POST(request: Request) {
const body = (await request.json()) as { name: string; price: number };
const product = await prisma.product.create({ data: { ...body, stock: 0 } });
return Response.json(product, { status: 201 });
}Example
curl -i -X POST localhost:3000/api/products -H "Content-Type: application/json" -d '{"name":"Clean Code","price":450}'Example output
HTTP/1.1 201 Created
content-type: application/json
{"id":3,"name":"Clean Code","price":450,"stock":0}When to Use Route Handlers
| Need | Use |
|---|---|
| Your own UI saves a form | Server Action |
| Your own UI reads data | Server Component (no API needed) |
| Mobile app or third party calls your API | Route Handler |
| Webhooks (Razorpay, Stripe, CMS) | Route Handler |
| Files: CSV export, RSS, images | Route Handler |
Note: GET handlers are dynamic by default in Next.js 15+. Add export const dynamic = 'force-static' to cache a GET response at build time.
Handlers Are Just Functions
Example
Because they use the standard Web API, you can call a handler directly in a test:
async function GET(request: Request): Promise<Response> {
const url = new URL(request.url);
const q = url.searchParams.get('q') ?? '';
const all = ['Redmi Note 14', 'Realme Narzo 70', 'iPhone 16', 'Redmi 13C'];
const hits = all.filter((n) => n.toLowerCase().includes(q.toLowerCase()));
return Response.json({ q, count: hits.length, hits });
}
async function main() {
const res = await GET(new Request('http://localhost:3000/api/search?q=redmi'));
console.log(res.status, res.headers.get('content-type'));
console.log(await res.json());
}
main();Output
200 application/json
{ q: 'redmi', count: 2, hits: [ 'Redmi Note 14', 'Redmi 13C' ] }