Keep API Route Handlers Thin — Delegate to Services
Impact: CRITICAL (prevents untestable, unauditable business logic in the API layer)
API route handlers that contain business logic, database queries, validation, and response formatting in one function are nearly impossible to unit test, difficult to audit for security, and guaranteed to accumulate technical debt. A "fat controller" is a code smell that violates the Single Responsibility Principle and makes it trivial to introduce security bugs — because the reviewer has to mentally parse 200+ lines to verify correctness.
Route handlers should do exactly three things: validate input, call a service, and return a response.
Incorrect (fat controller with everything in the route handler):
Rule of thumb: If your route handler exceeds 30 lines of actual logic (excluding imports and types), it is doing too much. Extract business logic to a service, validation to schemas, and cross-cutting concerns to middleware.
Detection hints:
# Find fat route handlers (files with POST/GET/PUT/DELETE exports over 50 lines)grep -rn "export async function POST\|export async function GET" src/app/api --include="*.ts" -l# Find direct database access in route handlersgrep -rn "createServerSupabaseClient\|supabase.*from.*select" src/app/api --include="*.ts" -l