Route Handlers (API Route.js)
5 questions found
What is a route handler in the Next.js App Router, and how do you create one?
Beginner
A route handler is a file named route.js placed inside a folder within your app directory, exporting functions named after HTTP methods like GET or POST, letting you build backend API endpoints directly within the App Router, similar to what API routes did in the Pages Router.
// app/api/hello/route.js
export async function GET() {
return Response.json({ message: 'Hello from a route handler' });
}
Real-world example
A weather application builds a simple route handler that returns current weather data as JSON, accessible at the api/hello path within its App Router based project.
Common follow-ups: Can a single route.js file export functions for multiple HTTP methods?;What is the difference between a route handler and a server action?
API Routes;Server Actions & Mutations
How do you read query parameters and the request body inside a route handler?
Intermediate
You access query parameters through the request URL's searchParams property, and read the request body by calling a method like json on the request object, which returns a promise that resolves to the parsed body data sent by the client.
export async function POST(request) {
const { searchParams } = new URL(request.url);
const category = searchParams.get('category');
const body = await request.json();
return Response.json({ category, received: body });
}
Real-world example
A search endpoint reads a category filter from the query string while also accepting a JSON body containing search preferences, combining both sources of input inside a single route handler.
Common follow-ups: How is reading the request body different between GET and POST route handlers?;What happens if the request body is not valid JSON?
API Routes;Form Handling & Validation in Next.js
How do you access dynamic route parameters inside a route handler defined with a dynamic segment?
Intermediate
The second argument passed to your route handler function contains a params object, which you await to access the dynamic segment values captured from the URL, letting you build endpoints like fetching a specific item by its id.
// app/api/products/[id]/route.js
export async function GET(request, { params }) {
const { id } = await params;
const product = await getProduct(id);
return Response.json(product);
}
Real-world example
A product API endpoint reads the product id directly from the dynamic route segment, letting it fetch and return the correct product details for any given id in the URL.
Common follow-ups: Can route handlers have both dynamic segments and query parameters at the same time?;How do you return a 404 response from within a route handler?
Dynamic Routes & Catch-All Segments;Error Handling & Not Found Pages
How would you implement rate limiting inside a route handler to prevent abuse of a public API endpoint?
Advanced
You track the number of requests coming from a specific identifier, such as an IP address or an API key, over a time window, usually using an external store like Redis for reliability across multiple server instances, and return a too many requests response once a client exceeds the allowed limit within that window.
export async function GET(request) {
const ip = request.headers.get('x-forwarded-for');
const requestCount = await getRequestCount(ip);
if (requestCount > 100) {
return Response.json({ error: 'Too many requests' }, { status: 429 });
}
await incrementRequestCount(ip);
return Response.json({ data: 'success' });
}
Real-world example
A public weather API endpoint limits each visitor to one hundred requests per hour, protecting the service from being overwhelmed by a single client sending excessive traffic.
Common follow-ups: What storage options work best for tracking rate limits across multiple server instances?;How do you communicate the remaining rate limit to API consumers?
Security Best Practices in Next.js;Edge Runtime vs Node.js Runtime
How do you set custom response headers, such as CORS headers, in a route handler to allow requests from a different domain?
Advanced
You construct your response using the Response constructor, passing a headers object that includes the necessary CORS headers like Access-Control-Allow-Origin, allowing browsers on other domains to successfully make requests to your API endpoint instead of being blocked by the browser's security policies.
export async function GET() {
return new Response(JSON.stringify({ data: 'hello' }), {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': 'https://partner-site.com'
}
});
}
Real-world example
A company exposes a public API that a trusted partner website needs to call directly from the browser, configuring the correct CORS headers so the partner's requests are not blocked.
Common follow-ups: What is the difference between allowing all origins and allowing a specific origin?;How do you handle preflight OPTIONS requests for CORS?
Security Best Practices in Next.js;API Routes