← headroom.walls.sh

Claude Code for REST API Development

Claude Code handles the repetitive work of API development — scaffolding routes, generating OpenAPI specs, writing validation, running test loops — while you focus on the business logic. This page covers the patterns that save the most time.

Set up your CLAUDE.md first

Tell Claude Code your framework and conventions once, so every session starts with context:

# API Project

## Stack
- Runtime: Node.js 20 + TypeScript
- Framework: Fastify 4
- Validation: Zod
- ORM: Prisma
- Test: Vitest + supertest

## Commands
- Dev: npm run dev
- Test: npm test
- Build: npm run build
- Lint: npm run lint

## Conventions
- Routes in src/routes/ — one file per resource
- Schemas in src/schemas/ — Zod schemas exported and reused
- Errors use HTTP status codes; body always `{ error: string, code?: string }`
- No console.log — use the logger (fastify.log)

With this in place, claude "add a DELETE /users/:id route" generates the route, schema, and test that match everything already in the codebase.

Scaffold a new API from a description

claude "scaffold a REST API for a task management app: tasks (id, title, description, status, dueDate, userId), users (id, email, name). Use Fastify + Zod + Prisma. Create the Prisma schema, route files, and Zod validation schemas. Follow the conventions in CLAUDE.md."

Claude Code will read your existing routes for structure, then generate consistent new ones. It won't invent a new pattern when the old one is right there.

Add a route to an existing API

claude "add PATCH /tasks/:id — allow updating title, description, status, and dueDate. Validate with Zod (all fields optional). Return 404 if the task doesn't exist or doesn't belong to the authenticated user. Add a test."

Claude Code reads the existing GET /tasks/:id handler to match its auth check pattern, writes the PATCH, writes the Zod partial schema, and generates a supertest that covers the 404 path.

Generate an OpenAPI spec from existing routes

claude "read all route files in src/routes/ and generate an OpenAPI 3.1 spec at docs/openapi.yaml. Include all request/response schemas, path parameters, and error responses. Derive descriptions from the route and schema names."

For Fastify: Claude Code can also wire up @fastify/swagger to auto-generate the spec from your schemas at runtime.

claude "install @fastify/swagger and @fastify/swagger-ui. Register both plugins. Annotate each route with the schema property so the spec generates automatically. Expose /docs as the Swagger UI."

Write input validation

claude "add Zod validation to all routes in src/routes/users.ts that are missing it. Infer the TypeScript types from the schemas. Add a 400 response with a clear error message for invalid input."

Validation schemas become the single source of truth — Claude Code will use them to type the request body and generate the OpenAPI spec automatically if you have swagger registered.

Error handling patterns

claude "add a global error handler to the Fastify instance. Map Zod validation errors to 400 with the field path and message. Map Prisma's P2025 (not found) to 404. All other errors get 500. Never leak a stack trace in production (check NODE_ENV)."

Once you have a global handler, every route gets consistent errors without try/catch boilerplate. Claude Code will remove redundant try/catch blocks from existing routes once the handler is in place — just ask it to.

Run the test loop unattended

claude "write integration tests for all routes in src/routes/tasks.ts using supertest and Vitest. Cover: happy path, 400 invalid input, 401 unauthenticated, 404 not found, 403 wrong user. Run the tests and fix any failures."

Claude Code runs the tests after writing them, then iterates on failures until the suite is green — without you watching. The test-fix loop is the pattern that saves the most clock time.

Refactor an existing API

claude "the routes in src/routes/ use express-validator for validation but the rest of the codebase uses Zod. Migrate all routes to Zod schemas. Keep the same request/response shapes — this is a refactor, not a redesign. Run tests after each file."

Give Claude Code a clear constraint ("same shapes, just different library") and it will migrate methodically without drifting the API contract.

Authentication middleware

claude "add JWT authentication middleware. Use the jsonwebtoken package. The middleware should extract the Bearer token from Authorization header, verify it with JWT_SECRET from env, and attach the decoded payload to request.user. Return 401 if the token is missing or invalid. Apply it to all routes except POST /auth/login and POST /auth/register."
claude "write tests for the auth middleware: valid token passes through, expired token returns 401, tampered token returns 401, missing header returns 401."

Database migration workflow

claude "I need to add a 'tags' field to tasks — it should be a string array. Update the Prisma schema, generate a migration, update the Zod schemas, update the routes (tags is optional on create/update, returned on all reads), and update the tests."

Claude Code handles the whole chain: schema → migration → routes → tests. The migration is generated (not run — it asks before touching the database by default) so you can review it first.

Monitor session budget during API work

API development with test loops burns session budget faster than manual coding. A test-fix loop that iterates 8 times (read → edit → run tests → read errors → edit → run again…) can consume 15–20% of your 5-hour window without you noticing.

Headroom — see your session budget while the test loop runs

When Claude Code is running your test suite and iterating on failures, your session meter is moving. Headroom shows your Claude Code session (5h) and weekly (7d) utilization live in the macOS menu bar — color-coded from calm to amber to red. No token, no API key: it reads the file Claude Code writes to ~/.claude/.

Install in one line:

brew install patwalls/tap/headroom

Start a long API refactor, glance at the menu bar — that's it. You'll know when to wrap up the session before the limit cuts it short.

Common Claude Code API patterns

TaskPrompt pattern
Add routeadd POST /resource — [spec]. Follow the pattern in GET /resource/:id
Add paginationadd cursor-based pagination to GET /tasks — page + limit params, return nextCursor
Rate limitingadd rate limiting to POST /auth/login — 5 attempts per 15 minutes per IP
Response cachingadd ETag caching to GET /tasks/:id — 304 on match
Health checkadd GET /health that checks the database connection and returns 200 or 503

What Claude Code won't do well without help

Claude Code is great at generating consistent, correct code from your existing patterns. It's less reliable for: designing the right data model from scratch (that's a design decision, not a coding task), deciding on auth strategy (JWT vs sessions vs API keys — know what you want before asking), and performance optimization without profiling data (always provide the slow query or trace).


Writing tests with Claude Code
Claude Code for TypeScript
Debugging with Claude Code
Claude Code hooks system