npx skills add https://github.com/nickcrew/claude-ctx-plugin --skill api-design-patternsSKILL.md
API Design Patterns
Expert guidance for designing scalable, maintainable REST and GraphQL APIs with industry-standard patterns for versioning, pagination, error handling, authentication, and service contracts.
When to Use This Skill
- Designing new REST or GraphQL APIs from scratch
- Refactoring existing APIs for better scalability and consistency
- Defining service contracts for microservices architectures
- Implementing versioning strategies for API evolution
- Standardizing error handling and response formats across services
- Designing pagination for large datasets
- Implementing HATEOAS or hypermedia-driven APIs
- Creating API specifications (OpenAPI, GraphQL Schema)
Core Principles
1. Resource-Oriented Design (REST)
URLs represent resources, not actions:
✓ GET /users/123
✓ POST /users
✓ PUT /users/123
✓ DELETE /users/123
✗ GET /getUser?id=123
✗ POST /createUser
✗ POST /deleteUser
Use HTTP methods semantically:
- GET: Retrieve resource(s), idempotent, cacheable
- POST: Create resource, non-idempotent
- PUT: Replace entire resource, idempotent
- PATCH: Partial update, idempotent
- DELETE: Remove resource, idempotent
2. Consistent Naming Conventions
Resources: /users, /orders, /products (plural nouns)
Nested: /users/123/orders
Collections: /users?status=active&page=2
Sub-resources: /users/123/settings
Actions (rare): /users/123/activate (POST)
3. HTTP Status Codes
Success:
- 200 OK: Standard response for GET, PUT, PATCH
- 201 Created: Resource created (POST), return Location header
- 202 Accepted: Async processing started
- 204 No Content: Success with no response body (DELETE)
Client Errors:
- 400 Bad Request: Invalid syntax or validation failure
- 401 Unauthorized: Authentication required or failed
- 403 Forbidden: Authenticated but insufficient permissions
- 404 Not Found: Resource doesn't exist
- 409 Conflict: State conflict (duplicate, version mismatch)
- 422 Unprocessable Entity: Semantic validation failure
- 429 Too Many Requests: Rate limit exceeded
Server Errors:
- 500 Internal Server Error: Unexpected server failure
- 502 Bad Gateway: Upstream service failure
- 503 Service Unavailable: Temporary overload or maintenance
- 504 Gateway Timeout: Upstream timeout
Versioning Strategies
URI Versioning (Most Common)
GET /v1/users/123
GET /v2/users/123
Pros: Clear, easy to route, browser-testable
Cons: URL proliferation, cache fragmentation
When: Public APIs, major breaking changes
Header Versioning
GET /users/123
Accept: application/vnd.myapi.v2+json
Pros: Clean URLs, content negotiation
Cons: Harder to test, caching complexity
When: Internal APIs, minor version differences
Query Parameter Versioning
GET /users/123?version=2
Pros: Simple, backward compatible
Cons: Pollutes query space, inconsistent
When: Rare, legacy compatibility
Deprecation Headers
Sunset: Sat, 31 Dec 2024 23:59:59 GMT
Deprecation: true
Link: <https://api.example.com/v2/users/123>; rel="successor-version"
Pagination Patterns
Offset-Based Pagination
GET /users?limit=20&offset=40
Response:
{
"data": [...],
"pagination": {
"limit": 20,
"offset": 40,
"total": 1543
},
"links": {
"next": "/users?limit=20&offset=60",
"prev": "/users?limit=20&offset=20"
}
}
Pros: Simple, predictable, supports total count
Cons: Inconsistent with concurrent writes, performance degrades
When: Small datasets, stable data, admin UIs
Cursor-Based Pagination
GET /users?limit=20&cursor=eyJpZCI6MTIzfQ
Response:
{
"data": [...],
"pagination": {
"next_cursor": "eyJpZCI6MTQzfQ",
"has_more": true
},
"links": {
"next": "/users?limit=20&cursor=eyJpZCI6MTQzfQ"
}
}
Pros: Consistent with writes, scalable, efficient
Cons: No total count, can't jump to arbitrary page
When: Large datasets, real-time feeds, infinite scroll
Keyset Pagination (Seek Method)
GET /users?limit=20&after_id=123&created_after=2024-01-01T00:00:00Z
Pros: Most performant, index-friendly
Cons: Requires sortable field, complex queries
When: Very large datasets, time-series data
Error Response Format
Standard Error Schema
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{
"field": "email",
"code": "INVALID_FORMAT",
"message": "Email format is invalid"
},
{
"field": "age",
"code": "OUT_OF_RANGE",
"message": "Age must be between 18 and 120"
}
],
"request_id": "req_a3f7c9b2",
"timestamp": "2024-01-15T10:30:00Z",
"documentation_url": "https://docs.api.com/errors/VALIDATION_ERROR"
}
}
Error Code Patterns
Format: CATEGORY_SPECIFIC_REASON
Authentication:
- AUTH_MISSING_TOKEN
- AUTH_INVALID_TOKEN
- AUTH_EXPIRED_TOKEN
Authorization:
- AUTHZ_INSUFFICIENT_PERMISSIONS
- AUTHZ
...
Repository Stats
Stars7
Forks2
LicenseMIT License