API Design
Use this for API contracts that other code, users, or services depend on.
Project Fit Check
Before changing an API:
- Read existing routes, schemas, OpenAPI/GraphQL docs, clients, tests, and auth rules.
- Identify consumers: UI, external users, workers, webhooks, integrations, or internal packages.
- Preserve existing naming, error shape, pagination style, and versioning policy unless the task is to change them.
- Treat compatibility as a product constraint.
- If documentation is missing, add the smallest useful contract near the existing source of truth.
Contract Rules
- Read every module the contract touches before drafting it, not after the first draft. A draft written from an assumed call graph is wrong about the guards, limits, and auth it has to preserve, and the correction costs more than the reading would have.
- Validate input at the boundary.
- Make response shape stable and documented.
- Use machine-readable error codes plus human-readable messages.
- Keep outcomes distinct when their causes differ. A request the system chose not to attempt is not a request that failed. Recording them as one outcome invents a failure, and downstream logic that suppresses retries on failure then suppresses the retry that would have succeeded.
- Keep auth and ownership checks at the strongest available boundary.
- Make pagination, filtering, sorting, and limits explicit.
- Keep idempotency clear for create/update/retry paths.
- Avoid leaking provider errors or internal stack details.
REST Rules
- Use resources and actions consistently.
- Choose status codes deliberately.
- Keep destructive operations explicit.
- Support partial failure only when the client can act on it.
- Use versioning when breaking changes cannot be coordinated.
GraphQL Rules
- Design schema around consumer needs, not database tables.
- Keep nullability meaningful.
- Avoid resolver waterfalls; batch where needed.
- Make authorization explicit per object or field where sensitivity differs.
- Deprecate before removing fields.
Verification
- schema/typecheck for contracts
- unit tests for validation and errors
- integration tests for auth, pagination, and persistence
- client or e2e tests for user-visible flows
Red Flags
- silent response shape change
- unbounded list endpoint
- inconsistent error format
- auth only in the frontend
- endpoint mirrors database internals
- breaking change without migration or version plan