Using GET to delete resources or POST for all mutations violates HTTP semantics in ways that cause real damage: browsers and CDNs will cache or prefetch GET endpoints that actually mutate state, link prefetchers can trigger deletes without user intent, and CWE-749 (exposed dangerous methods) applies when destructive operations are reachable via safe-method verbs. Semantically incorrect methods also break API consumers who rely on HTTP conventions — retry logic in HTTP clients retries GET and PUT as safe/idempotent but not POST.
High because GET-based mutations can be triggered by prefetchers, cached by CDNs, or exploited via CSRF — any of which produces unintended data destruction or exposure.
Align each route handler export in app/api/ with its actual semantic in one pass: GET reads only, POST creates, PATCH partially updates, PUT replaces, DELETE removes. In Next.js App Router this means changing the exported function name:
// Before (wrong)
export async function GET(req: Request) {
await db.user.delete({ where: { id: req.nextUrl.searchParams.get('id') } })
}
// After (correct)
export async function DELETE(req: Request) {
const { id } = await req.json()
await db.user.delete({ where: { id } })
}
Update all client-side fetch calls to use the matching method. Work through your route list systematically — most AI-generated APIs default POST for everything and need a full sweep.
saas-api-design.api-consistency.http-methods-correcthighexport async function GET, export async function POST, etc. in Next.js App Router, or req.method === 'POST' branching in Pages Router handlers./api/delete-user?id=123).app/api/ route files. Use GET for safe, idempotent reads. Use POST for resource creation or non-idempotent actions. Use PUT to replace a resource entirely (full update), PATCH for partial updates, and DELETE for removal. Update both the route handler export names and any client-side fetch calls. Most AI-generated APIs default to POST for everything — work through your route list and reassign appropriately.