plugins/backend-toolkit/skills/api-design/SKILL.md
Choose the API protocol (REST / GraphQL / gRPC) by traffic shape and design resources, versioning, and async patterns. Use when adding a new API surface, designing a service boundary, or when clients complain about over/under-fetching. Not for the schema/error envelope details (use api-contract) or per-resource access control (use authorization).
npx skillsauth add jaykim88/claude-ai-engineering api-designInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Pick the right protocol for each API surface by traffic characteristics — not by fashion — and model resources, versioning, and async operations so the contract can evolve without breaking clients.
Universal — protocol selection criteria (latency, client shaping needs, internal vs external), resource modeling, and versioning strategy apply to any language; only the framework's routing/serialization differs.
Choose protocol by traffic shape
Model resources (REST)
/orders/{id} not /getOrder)/orders/{id}/items, not 4 levels)Design versioning before v1 ships
/v1/) — simplest, most visibleAsync / long-running operations
202 Accepted + a status resource (/operations/{id}) for jobs > a few secondsbackground-jobs skillValidate the design
| ❌ Anti-pattern | ✅ Correct |
|---|---|
| Verbs in paths (/createUser) | Nouns + HTTP methods (POST /users) |
| GraphQL "because it's modern" for a simple CRUD API | REST default; GraphQL only when field-shaping is a real need |
| Breaking change shipped without a version bump | New version OR additive-only change (see api-contract) |
| Deep nesting (/a/{}/b/{}/c/{}) | Max one level; use query params / sub-resource links |
docs/adr/ADR-NNN-api-<surface>.md — protocol choice + rationale + versioning policyfeat(api): design <surface> endpoints [protocol: REST|gRPC|GraphQL]@nestjs/swagger for OpenAPI generation@nestjs/graphql (code-first) + DataLoader for N+1@nestjs/microservices gRPC transport + .proto contractsenableVersioning({ type: VersioningType.URI })api-contract — once protocol is chosen, define the schema-first contract thereschema-design — resource modeling aligns with DB schemaauthorization — per-resource access controldevelopment
Design webhooks correctly on both sides — sending (HMAC signing, retries with backoff, at-least-once) and receiving (verify signature on raw body, enqueue + 200 fast, dedupe on event id). Use when adding webhook delivery or consuming a provider's webhooks. Not for internal service-to-service events (use async-messaging) or general outbound-call retry policy (use resilience-patterns).
testing
Use transactions and isolation levels correctly — keep them short, no network calls inside, explicit isolation, retry on serialization conflicts, and choose optimistic vs pessimistic locking. Use when a write spans multiple tables, when concurrent updates corrupt data, or when designing money/inventory flows. Not for cross-service event delivery (use async-messaging Outbox) or schema-level constraints (use schema-design).
development
Backend testing pyramid — unit for pure logic, integration against a real DB (Testcontainers), and consumer-driven contract testing (Pact) for service boundaries. Use before a feature, after a bug fix, or when services break each other on deploy. Not for load testing (use performance-profiling) or security testing (use backend-security-audit).
data-ai
Design a relational schema — normalize to 3NF then denormalize with justification, choose the right Postgres index type per data shape, enforce constraints at the DB. Use when modeling a new domain, when queries are slow, or before a migration. Not for diagnosing slow queries (use query-optimization) or shipping the change without downtime (use migration-strategy).