api-patterns

API design principles and decision-making. REST vs GraphQL vs tRPC selection, response formats, versioning, pagination. Teaches thinking, not fixed patterns.

$ 安裝

git clone https://github.com/xenitV1/claude-code-maestro /tmp/claude-code-maestro && cp -r /tmp/claude-code-maestro/skills/api-patterns ~/.claude/skills/claude-code-maestro

// tip: Run this command in your terminal to install the skill


name: api-patterns description: API design principles and decision-making. REST vs GraphQL vs tRPC selection, response formats, versioning, pagination. Teaches thinking, not fixed patterns.

API Patterns

API design principles and decision-making for 2025. Learn to THINK, not copy fixed patterns.


⚠️ How to Use This Skill

This skill teaches decision-making principles, not fixed JSON to copy.

  • ASK user for API style preference when unclear
  • Choose pattern based on CONTEXT and clients
  • Don't default to REST for everything

1. API Style Selection (2025)

Decision Tree

Who are the API consumers?
│
├── Public API / Multiple platforms
│   └── REST + OpenAPI (widest compatibility)
│
├── Complex data needs / Multiple frontends
│   └── GraphQL (flexible queries)
│
├── TypeScript frontend + backend (monorepo)
│   └── tRPC (end-to-end type safety)
│
├── Real-time / Event-driven
│   └── WebSocket + AsyncAPI
│
└── Internal microservices
    └── gRPC (performance) or REST (simplicity)

Comparison Principles

FactorRESTGraphQLtRPC
Best forPublic APIsComplex appsTS monorepos
Learning curveLowMediumLow (if TS)
Over/under fetchingCommonSolvedSolved
Type safetyManual (OpenAPI)Schema-basedAutomatic
CachingHTTP nativeComplexClient-based
ToolingExtensiveGoodTS only

Selection Questions to Ask:

  1. Who are the API consumers?
  2. Is the frontend TypeScript?
  3. How complex are the data relationships?
  4. Is caching critical?
  5. Public or internal API?

2. REST Principles (Not Fixed JSON)

Resource Naming Rules

Principles:
├── Use NOUNS, not verbs (resources, not actions)
├── Use PLURAL forms (/users not /user)
├── Use lowercase with hyphens (/user-profiles)
├── Nest for relationships (/users/123/posts)
└── Keep shallow (max 3 levels deep)

HTTP Method Selection

MethodPurposeIdempotent?Body?
GETRead resource(s)YesNo
POSTCreate new resourceNoYes
PUTReplace entire resourceYesYes
PATCHPartial updateNoYes
DELETERemove resourceYesNo

Status Code Selection Guide

SituationCodeWhy
Success (read)200Standard success
Created201New resource created
No content204Success, nothing to return
Bad request400Malformed request
Unauthorized401Missing/invalid auth
Forbidden403Valid auth, no permission
Not found404Resource doesn't exist
Conflict409State conflict (duplicate)
Validation error422Valid syntax, invalid data
Rate limited429Too many requests
Server error500Our fault

3. Response Format Principles

Consistency is Key

Choose a format and STICK TO IT across entire API.

Common patterns:
├── Envelope pattern ({ success, data, error })
├── Direct data (just return the resource)
└── HAL/JSON:API (hypermedia)

Error Response Principles

Include:
├── Error code (for programmatic handling)
├── User message (for display)
├── Details (for debugging, field-level errors)
├── Request ID (for support)
└── NOT internal details (security!)

Pagination Principles

TypeBest ForTrade-offs
OffsetSimple, jumpablePerformance on large datasets
CursorLarge datasetsCan't jump to page
KeysetPerformance criticalRequires sortable key

Selection Questions:

  1. How large is the dataset?
  2. Do users need to jump to specific pages?
  3. Is data frequently changing?

4. GraphQL Principles

When to Use GraphQL

✅ Good fit:
├── Complex, interconnected data
├── Multiple frontend platforms
├── Clients need flexible queries
├── Evolving data requirements
└── Reducing over-fetching matters

❌ Poor fit:
├── Simple CRUD operations
├── File upload heavy
├── HTTP caching important
└── Team unfamiliar with GraphQL

Schema Design Principles

Principles:
├── Think in graphs, not endpoints
├── Design for evolvability (no versions)
├── Use connections for pagination
├── Be specific with types (not generic "data")
└── Handle nullability thoughtfully

Security Considerations

Protect against:
├── Query depth attacks → Set max depth
├── Query complexity → Calculate cost
├── Batching abuse → Limit batch size
├── Introspection → Disable in production

5. tRPC Principles

When to Use tRPC

✅ Perfect fit:
├── TypeScript on both ends
├── Monorepo structure
├── Internal tools
├── Rapid development
└── Type safety critical

❌ Poor fit:
├── Non-TypeScript clients
├── Public API
├── Need REST conventions
└── Multiple language backends

Key Benefits

Why tRPC:
├── Zero schema maintenance
├── End-to-end type inference
├── IDE autocomplete across stack
├── Instant API changes reflected
└── No code generation step

Integration Patterns

Common setups:
├── Next.js + tRPC (most common)
├── Monorepo with shared types
├── Remix + tRPC
└── Any TS frontend + backend

6. Versioning Strategies

Decision Factors

StrategyImplementationTrade-offs
URI/v1/usersClear, easy caching
HeaderAccept-Version: 1Cleaner URLs, harder discovery
Query?version=1Easy to add, messy
NoneEvolve carefullyBest for internal, risky for public

Versioning Philosophy

Consider:
├── Public API? → Version in URI
├── Internal only? → May not need versioning
├── GraphQL? → Typically no versions (evolve schema)
├── tRPC? → Types enforce compatibility

7. Authentication Patterns

Selection Guide

PatternBest For
JWTStateless, microservices
SessionTraditional web, simple
OAuth 2.0Third-party integration
API KeysServer-to-server, public APIs
PasskeyModern passwordless (2025+)

JWT Principles

Important:
├── Always verify signature
├── Check expiration
├── Include minimal claims
├── Use short expiry + refresh tokens
└── Never store sensitive data in JWT

8. Rate Limiting Principles

Why Rate Limit

Protect against:
├── Brute force attacks
├── Resource exhaustion
├── Cost overruns (if pay-per-use)
└── Unfair usage

Strategy Selection

TypeHowWhen
Token bucketBurst allowed, refills over timeMost APIs
Sliding windowSmooth distributionStrict limits
Fixed windowSimple counters per windowBasic needs

Response Principles

Include in headers:
├── X-RateLimit-Limit (max requests)
├── X-RateLimit-Remaining (requests left)
├── X-RateLimit-Reset (when limit resets)
└── Return 429 when exceeded

9. Documentation Principles

OpenAPI/Swagger

Include:
├── All endpoints with examples
├── Request/response schemas
├── Authentication requirements
├── Error response formats
└── Rate limiting info

Good Documentation Has

Essentials:
├── Quick start / Getting started
├── Authentication guide
├── Complete API reference
├── Error handling guide
├── Code examples (multiple languages)
└── Changelog

10. Decision Checklist

Before designing an API:

  • Asked user about API consumers?
  • Chosen API style for THIS context? (REST/GraphQL/tRPC)
  • Defined consistent response format?
  • Planned versioning strategy?
  • Considered authentication needs?
  • Planned rate limiting?
  • Documentation approach defined?

11. Anti-Patterns to Avoid

❌ DON'T:

  • Default to REST for everything (consider tRPC/GraphQL)
  • Use verbs in REST endpoints (/getUsers)
  • Return inconsistent response formats
  • Expose internal errors to clients
  • Skip rate limiting
  • Ignore pagination for lists
  • Version without strategy

✅ DO:

  • Choose API style based on context
  • Ask about client requirements
  • Document thoroughly
  • Use appropriate status codes
  • Plan for evolution

Remember: API design is about decision-making for YOUR specific context. Don't copy patterns blindly—think about what serves your consumers best.