Good Code
The good version keeps the HTTP API in a route.ts file and returns explicit JSON with a 404 when the record is missing.
Lesson 10
Use route handlers for HTTP APIs and keep them separate from page UI.
import { NextResponse } from "next/server";
import { getReview } from "@/lib/reviews";
export async function GET(
_request: Request,
context: RouteContext<"/api/reviews/[id]">,
) {
const { id } = await context.params;
const review = await getReview(id);
// The route handler validates lookup results and returns explicit HTTP status.
if (!review) {
return NextResponse.json(
{ error: "Review not found." },
{ status: 404 },
);
}
return NextResponse.json({ review });
}import { getReview } from "@/lib/reviews";
// Mixing GET and page UI in one file blurs the App Router boundary.
export async function GET() {
const review = await getReview("current");
return Response.json(review);
}
export default async function ReviewPage() {
const review = await getReview("current");
return <h1>{review.title}</h1>;
}The good version keeps the HTTP API in a route.ts file and returns explicit JSON with a 404 when the record is missing.
The bad version mixes a route handler and page UI at the same segment, which conflicts with App Router route resolution and blurs the API boundary.