Next.js App Router API patterns — Route Handlers, Server Actions, middleware, validation, caching, error handling
92
90%
Does it follow best practices?
Impact
95%
1.58xAverage score across 5 eval scenarios
Passed
No known issues
{
"context": "Tests whether the agent proactively applies Next.js App Router best practices when building a CRUD API. The task does not mention validation, error handling, caching, or params awaiting -- the agent should add these from knowledge of the tile patterns.",
"type": "weighted_checklist",
"checklist": [
{
"name": "Params awaited in dynamic routes",
"description": "Dynamic route handlers ([id]/route.ts) await the params object before accessing id: 'const { id } = await params' with the type { params: Promise<{ id: string }> }. Not accessing params.id directly.",
"max_score": 15
},
{
"name": "Zod or schema validation on input",
"description": "POST and PUT handlers validate the request body using zod (or equivalent schema library) with safeParse -- checking name, price, and category constraints rather than manual if-checks",
"max_score": 14
},
{
"name": "Structured error responses",
"description": "All error responses use a consistent shape like { error: { code, message } } with appropriate HTTP status codes (400 for validation, 404 for not found, 409 for duplicate name) -- not raw strings or inconsistent formats",
"max_score": 13
},
{
"name": "request.json() wrapped in try/catch",
"description": "POST and PUT handlers wrap request.json() in try/catch to handle malformed JSON, returning a 400 error",
"max_score": 10
},
{
"name": "NextResponse.json used correctly",
"description": "Handlers return NextResponse.json() with explicit status codes -- 201 for creation, 204 for deletion, 404 for not found -- not Express-style res.status().json()",
"max_score": 10
},
{
"name": "GET caching control",
"description": "GET handlers either export dynamic = 'force-dynamic' or use request-dependent APIs to prevent stale cached responses in production, OR the menu page uses fetch with explicit revalidation options",
"max_score": 10
},
{
"name": "No internal error leaks",
"description": "Unexpected errors return a generic message (e.g. 'An unexpected error occurred') with 500 status -- no stack traces or internal details in responses",
"max_score": 8
},
{
"name": "Error boundary for menu page",
"description": "An error.tsx file with 'use client' directive exists for the menu route segment, providing a user-facing error boundary",
"max_score": 8
},
{
"name": "CRUD endpoints functional",
"description": "All five CRUD operations are implemented and return appropriate data shapes with correct status codes",
"max_score": 12
}
]
}