API Route Handlers Pattern
Relevant source files
The following files were used as context for generating this wiki page:
The API Route Handlers Pattern in the Recoup API project is a structured architectural approach designed to separate concerns between network entry points and core business logic. Built on Next.js 16 App Router, the pattern enforces a "thin wrapper" strategy for route files, delegating orchestration to dedicated handler functions. This ensures modularity, testability, and consistent response formatting across the service.
Sources: dev/API-AGENT.md:12-25, CLAUDE.md:38-45
Architectural Overview
The architecture follows a strict hierarchy where requests flow through predefined layers. Each layer has a specific responsibility:
- Route Layer (
app/api/): Acts as the entry point, defining HTTP methods and delegating to handlers. - Handler Layer (
lib/{domain}/): Orchestrates the request by calling validators and business logic. - Validation Layer (
lib/{domain}/): Uses Zod to ensure request data adheres to expected schemas. - Business Logic Layer (
lib/{domain}/): Contains pure logic or interacts with external services/database.
Request Flow Diagram
The following diagram illustrates the standard data flow from an incoming HTTP request to the final response.
Sources: dev/API-AGENT.md:70-85, CLAUDE.md:286-300
Core Components
1. Route Wrappers
Route files located in app/api/**/route.ts are required to be thin wrappers. They primarily handle CORS preflight requests via OPTIONS and export standard HTTP method functions (GET, POST, etc.) that immediately invoke a corresponding handler.
Sources: dev/API-AGENT.md:72-105
2. Domain Handlers
Handlers are the "orchestrators" of the API. They are responsible for:
- Parsing the incoming
NextRequest. - Invoking validation functions.
- Executing business logic.
- Formatting the
NextResponsewith appropriate status codes and CORS headers.
3. Validation Functions
Validation is handled using Zod. Patterns involve creating specific validator files (validate{Resource}{Query|Body}.ts) that return either the validated data object or a NextResponse error object if parsing fails.
Sources: dev/API-AGENT.md:160-200, lib/content/validateCreateContentBody.ts:47-75
Authentication Integration
A critical part of the handler pattern is the use of validateAuthContext(). This utility is invoked within handlers to resolve identity and permissions. It supports multiple authentication methods:
x-api-keyheaderAuthorization: Bearertokens
Handlers use this to derive the accountId rather than accepting it as an input field in the request body, which prevents impersonation.
Sources: CLAUDE.md:214-235, lib/content/validateCreateContentBody.ts:77-85
Implementation Standards
Naming Conventions
| Component | Naming Convention | Example |
|---|---|---|
| Handler Functions | {verb}{Resource}Handler | createChatHandler |
| Validator Functions | validate{Resource}{Query|Body} | validateCreateContentBody |
| Zod Schemas | {resource}{Query|Body}Schema | createContentBodySchema |
| Route Files | Always route.ts | app/api/chats/route.ts |
Sources: dev/API-AGENT.md:230-245, AGENTS.md:230-245
Response Shapes
The project enforces flat JSON response structures. Success responses always include a status: "success" field, while errors include status: "error" and an error message.
Sources: dev/API-AGENT.md:214-225, CLAUDE.md:158-166
Error Handling Pattern
Handlers must wrap logic in try/catch blocks. Caught errors are logged and returned as 500 status responses with a consistent error structure to ensure the client receives a valid JSON payload even during failures.
Sources: dev/API-AGENT.md:135-154, lib/content/getContentValidateHandler.ts:32-42
Summary
The API Route Handlers Pattern provides a predictable and scalable framework for building the Recoup API. By strictly separating validation and logic from the routing layer, the system remains maintainable and allows for extensive unit testing of business logic and request handlers independently of the Next.js runtime environment.
Sources: dev/API-AGENT.md:270-285, lib/chats/tests/createChatHandler.test.ts:1-50