Skip to content

@tank/api-design-mastery

1.1.0
Skill

Description

REST, GraphQL, and tRPC API design for backend engineers. Covers endpoint design, HTTP methods, status codes, API versioning, error contracts (RFC 7807/9457), pagination (offset, cursor, keyset, Relay connections), auth (API keys, JWT, OAuth 2.0 PKCE, Client Credentials), RBAC, rate limiting.

Triggered by

REST APIGraphQL schematRPCAPI versioningerror responseRFC 7807
Download
Review Recommended
tank install @tank/api-design-mastery

API Design Mastery

Core Philosophy

  1. Design for the consumer, not the database — API shape reflects use cases, not schema structure. Consumers should not need to understand your internals.
  2. Consistency over cleverness — Uniform patterns across all endpoints reduce cognitive load more than any individual optimization.
  3. Additive by default — Plan for backward compatibility from day one. Adding is safe; removing breaks clients.
  4. Errors are first-class citizens — Error contracts deserve the same design care as success responses. Use RFC 9457.
  5. Pick the right tool — REST for public APIs, GraphQL for multi-client data graphs, tRPC for TypeScript monorepos.

Quick-Start: Common Problems

"Which API style should I use?"

SignalChoose
Public API, third-party consumers, any client languageREST + OpenAPI
Multiple clients needing different data shapes (web + mobile + partner)GraphQL
TypeScript monorepo, internal full-stack app (Next.js/Remix)tRPC
Real-time data streams + existing REST/GraphQLAdd subscriptions (GraphQL / tRPC)
→ See references/trpc-patterns.md for the REST vs GraphQL vs tRPC comparison table

"How do I design this endpoint?"

  1. What is the resource (noun)? → /orders, not /createOrder
  2. What HTTP method? → GET (read) / POST (create) / PUT (replace) / PATCH (partial) / DELETE
  3. What status code on success? → 200/201/204
  4. What is the error contract? → RFC 7807 application/problem+json
  5. Does it change anything observable? → If yes, it must be POST/PUT/PATCH/DELETE → See references/rest-endpoint-design.md

"My API returns errors inconsistently"

  1. Adopt RFC 7807 Problem Details — type, title, status, detail, instance
  2. Use Content-Type: application/problem+json
  3. Add machine-readable code extension (SCREAMING_SNAKE_CASE)
  4. Add errors[] array for field validation failures
  5. Include requestId for server-side correlation → See references/error-contracts.md

"Clients are breaking when I change the API"

  1. Was it a breaking change? → See breaking vs non-breaking table in references/api-versioning.md
  2. If breaking: add new version; run old version in parallel
  3. Announce deprecation: Deprecation: true + Sunset: header (RFC 8594)
  4. Give clients ≄ 6 months; contact high-traffic users directly → See references/api-versioning.md

"Pagination is slow at deep pages"

  1. Offset/limit past page 100? → Switch to cursor pagination
  2. Need GraphQL? → Use Relay Cursor Connections spec
  3. REST? → Keyset pagination with opaque base64 cursor
  4. Index must cover all ORDER BY columns → See references/pagination-filtering.md

"Auth isn't secure"

  1. Server-to-server: API key (hashed, Authorization header, never URL param)
  2. User-delegated: OAuth 2.0 Authorization Code + PKCE
  3. Service-to-service: OAuth 2.0 Client Credentials
  4. All JWT access tokens: ≤ 15 min expiry; refresh tokens in httpOnly cookie → See references/auth-patterns.md

Decision Trees

HTTP Method Selection

OperationMethodIdempotent?Notes
Fetch resource or listGETYesNever has side effects
Create new resourcePOSTNoReturns 201 + Location header
Full replace (client provides all fields)PUTYesClient sends complete representation
Partial update (only changed fields)PATCHNo (unless designed)Client sends delta only
Remove resourceDELETEYesReturns 204 No Content
Trigger action (not a CRUD op)POSTDepends/orders/42/cancel

Error Status Code Selection

SituationCode
Can't parse request body400
Valid syntax, fails business validation422
No credentials provided401
Credentials valid, lacks permission403
Resource doesn't exist404
Duplicate / state conflict409
Permanently removed410
Rate limit exceeded429

GraphQL vs REST Error Handling

LayerRESTGraphQLtRPC
Transport errorsHTTP status + Problem DetailsHTTP 200 (partial) or 400HTTP status via TRPCError code
Field errorserrors[] in Problem Detailserrors[] array + extensions.codeZod error formatter

Reference Files

FileContents
references/rest-endpoint-design.mdResource modeling, URL naming, HTTP methods, status codes, idempotency, HATEOAS, request/response design
references/graphql-schema-design.mdType system, queries/mutations/subscriptions, N+1 problem, DataLoader, Relay connections spec, complexity limiting, security
references/trpc-patterns.mdinitTRPC setup, procedure types, Zod validation, middleware, context, router composition, error codes, subscriptions, adapters
references/api-versioning.mdBreaking vs non-breaking changes, URL/header/media-type strategies, deprecation workflow, Sunset header, Stripe versioning model
references/error-contracts.mdRFC 7807/9457 Problem Details, status code decision trees, field validation errors, error tracing, GraphQL and tRPC error formats
references/pagination-filtering.mdOffset, cursor, keyset pagination, Relay connections spec, sorting patterns, filtering operators, field selection
references/auth-patterns.mdAPI key design, JWT access+refresh pattern, OAuth 2.0 flows (Auth Code+PKCE, Client Credentials), RBAC, rate limiting algorithms

Command Palette

Search packages, docs, and navigate Tank