Agent skill
api-design-patterns
REST API design patterns including versioning strategies (URL, header, content negotiation), pagination (offset, cursor, keyset), filtering and sorting, error response formats (RFC 7807), authentication (JWT, OAuth 2.0, API keys), rate limiting, and OpenAPI specification. Use when designing APIs, documenting endpoints, implementing authentication, standardizing error responses, or reviewing API implementations.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/design/api-design-patterns
SKILL.md
API Design Patterns
Purpose: Comprehensive REST API design patterns for building consistent, scalable, and maintainable APIs.
When to use: Designing new APIs, documenting endpoints, implementing authentication/authorization, standardizing error responses, reviewing API implementations, or troubleshooting API issues.
For detailed examples, OpenAPI specs, and implementation guides: See reference.md
Core Principles
- Resources over actions - Use nouns not verbs in URLs
- Standard HTTP methods - GET/POST/PUT/PATCH/DELETE with correct semantics
- Predictable structure - Consistent patterns across all endpoints
- Client-friendly errors - Clear, actionable error messages
- Versioning from day one - APIs evolve, plan for it
- Security by default - Authentication and authorization required
REST Fundamentals
Resource Design
Resources are nouns, not verbs:
| Pattern | Example | Status |
|---|---|---|
| ✅ Good | GET /users, POST /orders |
Use nouns |
| ❌ Bad | GET /getUsers, POST /createOrder |
Avoid verbs |
Hierarchy reflects relationships:
/users # Collection
/users/{id} # Single resource
/users/{id}/orders # Nested collection
/users/{id}/orders/{orderId} # Nested resource
Naming conventions:
- Plural nouns:
/users,/orders,/products - Lowercase with hyphens:
/user-profilesnot/userProfiles - Keep shallow (max 3 levels)
HTTP Methods & Status Codes
Method Semantics
| Method | Purpose | Idempotent | Safe | Example |
|---|---|---|---|---|
| GET | Retrieve resource(s) | Yes | Yes | GET /users/123 |
| POST | Create resource | No | No | POST /users |
| PUT | Replace resource | Yes | No | PUT /users/123 |
| PATCH | Update resource | No | No | PATCH /users/123 |
| DELETE | Delete resource | Yes | No | DELETE /users/123 |
Idempotent: Multiple identical requests have same effect Safe: No side effects, read-only
Status Codes Reference
| Code | Meaning | Use When |
|---|---|---|
| 2xx Success | ||
| 200 OK | Success (with body) | GET, PUT, PATCH success |
| 201 Created | Resource created | POST success, return Location header |
| 204 No Content | Success (no body) | DELETE success |
| 4xx Client Errors | ||
| 400 Bad Request | Invalid syntax/data | Validation errors, malformed JSON |
| 401 Unauthorized | Missing/invalid auth | No token, expired token |
| 403 Forbidden | Insufficient permissions | Valid auth but not authorized |
| 404 Not Found | Resource doesn't exist | Invalid ID, deleted resource |
| 409 Conflict | Resource state conflict | Duplicate email, version mismatch |
| 422 Unprocessable Entity | Semantic errors | Valid JSON but business rule violation |
| 429 Too Many Requests | Rate limit exceeded | Client exceeded rate limit |
| 5xx Server Errors | ||
| 500 Internal Server Error | Unexpected error | Uncaught exceptions |
| 503 Service Unavailable | Temporarily down | Maintenance, overloaded |
For complete status code reference: See reference.md
API Versioning
Versioning Strategies Comparison
| Strategy | Example | Pros | Cons | Use When |
|---|---|---|---|---|
| URL Path | /v1/users |
Simple, visible, cacheable | URL changes | Public APIs |
| Header | Accept: vnd.api.v1+json |
Clean URLs | Hidden complexity | Enterprise APIs |
| Query Param | /users?version=1 |
Optional versioning | Less discoverable | Internal APIs |
URL Versioning (Recommended)
GET /v1/users
GET /v2/users
Rules:
- Major version only (v1, v2, v3)
- Breaking changes require new version
- Support N-1 versions (current + previous)
Breaking changes:
- Removing endpoints or fields
- Changing field types or validation
- Changing authentication requirements
Non-breaking changes (same version):
- Adding endpoints or optional fields
- Adding response fields
- Relaxing validation
For version deprecation headers and examples: See reference.md
Pagination
Pagination Strategies Comparison
| Strategy | Best For | Pros | Cons |
|---|---|---|---|
| Offset | Small datasets (<10K), user-facing pages | Simple, page numbers | Slow for large offsets, duplicates if data changes |
| Cursor | Large datasets, feeds/timelines | Fast, consistent | Opaque tokens, can't jump to page |
| Keyset | Large datasets, stable ordering | Fast, consistent, transparent | Requires indexed field, complex queries |
Offset Pagination
GET /users?limit=20&offset=40
Response:
{
"data": [...],
"pagination": {
"limit": 20,
"offset": 40,
"total": 1000
}
}
Cursor Pagination (Recommended)
GET /users?limit=20&cursor=eyJpZCI6MTIzfQ==
Response:
{
"data": [...],
"pagination": {
"next_cursor": "eyJpZCI6MTQzfQ==",
"has_more": true
}
}
Benefits: Fast, consistent results, works with real-time data
For cursor encoding and keyset pagination: See reference.md
Filtering & Sorting
# Simple filtering
GET /users?status=active&role=admin
# Multiple values (OR)
GET /users?status=active,pending
# Range filtering
GET /orders?min_amount=100&max_amount=500
# Sorting
GET /users?sort=created_at # Ascending
GET /users?sort=-created_at # Descending (- prefix)
GET /users?sort=last_name,first_name # Multiple fields
# Combined
GET /users?status=active&sort=-created_at&limit=20
Advanced Filtering (LHS Brackets)
GET /products?price[gte]=100&price[lte]=500
GET /users?tags[in]=admin,moderator
GET /articles?title[contains]=design
Operators: eq, ne, gt, gte, lt, lte, in, nin, contains, startsWith
Error Response Format
RFC 7807 Problem Details (Recommended)
{
"type": "https://api.example.com/errors/validation-failed",
"title": "Validation Failed",
"status": 400,
"detail": "One or more fields failed validation",
"instance": "/users",
"errors": [
{
"field": "email",
"message": "Email address is already in use",
"code": "EMAIL_DUPLICATE"
}
],
"trace_id": "abc123-def456-ghi789"
}
Error Response Fields
| Field | Required | Description |
|---|---|---|
type |
Yes | URI identifying error type (documentation link) |
title |
Yes | Human-readable summary |
status |
Yes | HTTP status code |
detail |
No | Specific explanation |
instance |
No | Request path or trace ID |
errors |
No | Field-specific errors |
trace_id |
No | Internal trace ID |
Response headers:
HTTP/1.1 400 Bad Request
Content-Type: application/problem+json
For error examples by status code: See reference.md
Authentication & Authorization
Authentication Patterns Comparison
| Pattern | Use Case | Stateless | Pros | Cons |
|---|---|---|---|---|
| JWT | Microservices, SPAs | Yes | Scalable, no DB lookup | Can't revoke before expiry |
| OAuth 2.0 | Third-party access | No | Industry standard, granular scopes | Complex setup |
| API Keys | Server-to-server | Yes | Simple | Less secure, no user context |
JWT Authentication (Recommended)
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Token endpoint:
POST /auth/token
{
"username": "user@example.com",
"password": "secret"
}
Response:
{
"access_token": "eyJhbGc...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "def50200..."
}
Best practices:
- Short-lived access tokens (15-60 min)
- Long-lived refresh tokens (7-30 days)
- Minimal claims (sub, role, exp, iat)
- Strong algorithm (RS256 or HS256)
OAuth 2.0 Flow
1. Client → Auth server: authorization request
2. User grants permission
3. Auth server → Client: authorization code
4. Client → Auth server: exchange code for token
5. Auth server → Client: access token + refresh token
Scopes:
read:users # Read user data
write:users # Create/update users
admin:* # Full admin access
API Keys (Server-to-Server)
X-API-Key: sk_live_51H2xPqF3...
Best practices:
- Prefix by environment:
sk_test_,sk_live_ - Hash in database
- Support key rotation
- Scope to specific permissions
For detailed OAuth flow, key management, and authorization patterns: See reference.md
Rate Limiting
Rate Limit Headers
# Standard headers (RateLimit Policy Draft)
HTTP/1.1 200 OK
RateLimit-Limit: 100
RateLimit-Remaining: 75
RateLimit-Reset: 1640000000
# After limit hit
HTTP/1.1 429 Too Many Requests
RateLimit-Remaining: 0
Retry-After: 60
Rate Limiting Strategies
| Strategy | Description | Use Case |
|---|---|---|
| Fixed Window | Count per fixed time window | Simple, allows 2x burst at edge |
| Sliding Window | Rolling time window | Smooth rate limiting |
| Token Bucket | Tokens refill, burst allowed | Variable load |
| Leaky Bucket | Constant rate, excess rejected | Strict rate limiting |
Rate limit tiers:
Free: 100 requests/hour
Basic: 1,000 requests/hour
Premium: 10,000 requests/hour
Enterprise: Custom limits
OpenAPI Specification
Use for: API documentation, client generation, validation
Basic structure:
openapi: 3.0.3
info:
title: User API
version: 1.0.0
paths:
/users:
get:
summary: List users
parameters:
- name: limit
in: query
schema:
type: integer
default: 20
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/UserList'
components:
schemas:
User:
type: object
properties:
id:
type: integer
name:
type: string
email:
type: string
format: email
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
security:
- BearerAuth: []
Tools:
- Swagger UI: Interactive docs
- Redoc: Clean, responsive docs
- OpenAPI Generator: Generate clients/servers
For complete OpenAPI examples: See reference.md
Quick Reference Checklist
Designing new API:
- Version from day one (URL path recommended)
- Use nouns for resources, plural names
- Standard HTTP methods (GET/POST/PUT/PATCH/DELETE)
- Pagination for collections (cursor recommended)
- Filtering and sorting via query params
- RFC 7807 error responses
- Authentication (JWT recommended)
- Rate limiting with standard headers
- OpenAPI specification
Endpoint design:
- Resource naming follows conventions
- Correct HTTP method and status codes
- Request validation with clear errors
- Consistent response structure
- Security headers (CORS, CSP)
- ETag/Last-Modified for caching
Documentation:
- OpenAPI spec complete
- Authentication flow documented
- Rate limits documented
- Error responses documented
- Example requests/responses
Common Patterns Summary
# List with pagination
GET /v1/users?limit=20&cursor=abc123
# Filter and sort
GET /v1/products?category=electronics&status=active&sort=-price
# Create
POST /v1/users
Authorization: Bearer <token>
# Update (partial)
PATCH /v1/users/123
Authorization: Bearer <token>
# Delete
DELETE /v1/users/123
Authorization: Bearer <token>
# Nested resources
GET /v1/users/123/orders
# Search
GET /v1/users?q=john&fields=name,email
# Batch operations
POST /v1/users/batch
{
"operations": [
{"op": "create", "data": {...}},
{"op": "update", "id": 123, "data": {...}}
]
}
For detailed examples, complete OpenAPI specs, implementation guides, and language-specific patterns: See reference.md
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?