jagreehal avatar

api-design

Build production-ready HTTP APIs with clean handlers, consistent error envelopes, health checks, COR

作者 jagreehal|オープンソース

API Design Patterns

Critical rules

  • Handlers only translate HTTP ↔ domain: validate at the edge, call fn(args, deps) / Result, map to response. No business logic in handlers.
  • One error envelope everywhere; ORPCError(code) must match ErrorResponse.code.
  • Shared domain-error → status mapping; /health and /ready; X-Request-ID in middleware once.
  • Mutations require Idempotency-Key; 429 includes Retry-After; drain with 503 on shutdown.
  • One file per route with co-located tests; compose routers via factories.
  • Before implementing routes or ops concerns, read references/patterns.md.

Workflow

  1. Define Zod input/output schemas at the framework boundary.
  2. Create a route factory createX({ deps }) that delegates to domain functions.
  3. Map domain errors through the shared status table and consistent envelope.
  4. Add health/ready, CORS, request ID middleware, idempotency, rate limits, shutdown — see references/patterns.md.
  5. Compose routers at module boundaries (createPostsRoutercreateApiRouter).
  6. Write co-located tests with call() — see references/testing.md.

Resources

Validation

  • Routes are factories with injected deps; handlers stay thin
  • Errors use one envelope; codes match
  • Shared status mapping; /health and /ready exist
  • Mutations honor Idempotency-Key; 429 has Retry-After; shutdown → 503
  • X-Request-ID set in middleware
  • Co-located success and error tests per route

Constraints

  • Internal calls and background jobs without HTTP are out of scope. Retry policy belongs in resilience.
  • Related: fn-args-deps, validation-boundary, result-types, resilience, observability.