Route Handlers
While Server Actions handle form submissions, there are times you need to build standard HTTP REST endpoints to expose data to external clients. Next.js supports this using Route Handlers.
1. Directory Setup for APIs
Route Handlers are defined using route.ts files inside the app directory.
src/app/
└── api/
└── products/
└── route.ts # Accessible at /api/productsSafety Rule
You cannot place a route.ts file in the same directory as a page.tsx file, as doing so would cause a route conflict.
2. Implementing GET and POST Handlers
Route Handlers support standard HTTP methods (such as GET, POST, PUT, DELETE). The functions receive a standard web Request object and return a Response (typically a NextResponse JSON wrapper):
// src/app/api/products/route.ts
import { NextResponse } from "next/server";
// Sample database store
const products = [
{ id: 1, name: "Database Book", price: 29 },
{ id: 2, name: "Keyboard Cover", price: 9 }
];
// Handle GET requests
export async function GET() {
return NextResponse.json(products);
}
// Handle POST requests
export async function POST(request: Request) {
try {
// Parse the JSON request body
const body = await request.json();
if (!body.name || !body.price) {
return NextResponse.json(
{ error: "Name and price parameters are required." },
{ status: 400 }
);
}
const newProduct = {
id: Date.now(),
name: body.name,
price: body.price
};
// Save item to database
console.log("Saving new product:", newProduct);
return NextResponse.json(newProduct, { status: 201 });
} catch (error) {
return NextResponse.json(
{ error: "Invalid request body content." },
{ status: 400 }
);
}
}3. Dynamic API Routes
To build dynamic API endpoints (such as retrieving a single product by ID), wrap the route directory in square brackets:
src/app/
└── api/
└── products/
└── [id]/
└── route.ts # Accessible at /api/products/123// src/app/api/products/[id]/route.ts
import { NextResponse } from "next/server";
interface RouteProps {
params: Promise<{ id: string }>;
}
export async function GET(request: Request, { params }: RouteProps) {
const resolvedParams = await params;
const productId = resolvedParams.id;
// Retrieve item details from database
console.log(`Loading product ID: ${productId}`);
return NextResponse.json({
id: productId,
name: "Specialized Item Details",
status: "instock"
});
}Published on Last updated: