--- name: fastify-api-design description: Use when adding or changing routes, schemas, or plugins in this Fastify API — keep endpoints validated, typed, and testable. license: MIT compatibility: Fastify ESM API in this boilerplate allowed-tools: Read metadata: stack: fastify --- # Fastify API Design ## Overview Keep the Fastify app small, testable, and schema-first. Build on the exported `createApp()` factory so tests can inject the server without binding a fixed port. ## Process 1. Register routes on the app returned by `createApp()` in `src/app.js`. 2. Define JSON schemas for request/response when the payload shape matters. 3. Return correct status codes (200/201 success, 400 client error, 404 not found). 4. Use Fastify's built-in error handler; do not leak stack traces in production. 5. Add a `test/` case that starts the app on port `0` and asserts responses. ## Plugin Order 1. Core plugins (cors, sensible) if needed 2. Route registration 3. Global error handler ## Testing - Integration tests: `app.listen({ port: 0 })`, `fetch` against `127.0.0.1`. - Extract pure helpers for unit tests when logic grows beyond route handlers. - Run `npm test` before every commit. ## Guidelines - Prefer route-level schemas over ad-hoc validation in handlers. - Keep handlers thin; move business logic to testable functions. - Read secrets from environment variables at startup, not from requests. - Prefer explicit routes over catch-all handlers. ## Anti-patterns - Bypassing Fastify validation with unvalidated `request.body` access. - Starting the server inside `createApp()` — keep listen in `server.js` only. - Global mutable state shared across requests.