Express API Design
Overview
Keep the Express app small, testable, and consistent. Build routes on the
exported createApp() factory so they can be tested without binding a port.
Process
- Add the route to
src/app.json the app returned bycreateApp(). - Validate and parse input explicitly; never trust request bodies or params.
- Return JSON for API routes with a clear shape and correct status codes (200/201 success, 400 client error, 404 not found, 500 server error).
- Centralize error handling with an error-handling middleware; do not leak stack traces in responses.
- Add a
test/case that starts the app on an ephemeral port and asserts the response.
Route Design
- Use nouns for resources (
/items,/items/:id), verbs via HTTP methods. - Version breaking changes (
/v2/...) or document compatibility in README. - Document request/response shapes in README or OpenAPI when the surface grows.
Middleware Order
- Security headers / CORS (if needed)
- Body parsers with size limits
- Authentication (if applicable)
- Routes
- 404 handler
- Error handler (last)
Testing
- Integration tests: spin up
createApp()on port0, usefetchagainsthttp://127.0.0.1:<port>/.... - Unit tests: pure functions extracted from handlers.
- Run
npm testbefore every commit.
Guidelines
- Keep handlers thin; move non-trivial logic into small functions you can unit test.
- Prefer explicit routes over broad catch-alls.
- Do not read secrets from the request; read configuration from environment variables at startup.
- Keep responses deterministic and documented in the README.
- Assume stateless serverless when deployed to Vercel — no in-memory sessions.
Deployment
See the shared deploy-vercel skill when shipping to Vercel.
Anti-patterns
- Business logic embedded in anonymous middleware chains.
- Returning raw
error.messageor stacks to clients. - Global mutable state shared across requests in serverless.


