designing-apis
Scannednpx machina-cli add skill ancoleman/ai-design-components/designing-apis --openclawDesigning APIs
Design well-structured, scalable APIs using REST, GraphQL, or event-driven patterns. Focus on resource design, versioning, error handling, pagination, rate limiting, and security.
When to Use This Skill
Use when:
- Designing a new REST, GraphQL, or event-driven API
- Establishing API design standards for a team or organization
- Choosing between REST, GraphQL, WebSockets, or message queues
- Planning API versioning and breaking change management
- Defining error response formats and HTTP status code usage
- Implementing pagination, filtering, and rate limiting patterns
- Designing OAuth2 flows or API key authentication
- Creating OpenAPI or AsyncAPI specifications
Do NOT use for:
- Implementation code (use
api-patternsskill for Express, FastAPI code) - Authentication implementation (use
auth-securityskill for JWT, sessions) - API testing strategies (use
testing-strategiesskill) - API deployment and infrastructure (use
deploying-applicationsskill)
Core Design Principles
Resource-Oriented Design (REST)
Use nouns for resources, not verbs in URLs:
✓ GET /users List users
✓ GET /users/123 Get user 123
✓ POST /users Create user
✓ PATCH /users/123 Update user 123
✓ DELETE /users/123 Delete user 123
✗ GET /getUsers
✗ POST /createUser
Nest resources for relationships (limit depth to 2-3 levels):
✓ GET /users/123/posts
✓ GET /users/123/posts/456/comments
✗ GET /users/123/posts/456/comments/789/replies (too deep)
For complete REST patterns, see references/rest-design.md
HTTP Method Semantics
| Method | Idempotent | Safe | Use For | Success Status |
|---|---|---|---|---|
| GET | Yes | Yes | Read resource | 200 OK |
| POST | No | No | Create resource | 201 Created |
| PUT | Yes | No | Replace entire resource | 200 OK, 204 No Content |
| PATCH | No | No | Update specific fields | 200 OK, 204 No Content |
| DELETE | Yes | No | Remove resource | 204 No Content, 200 OK |
Idempotent means multiple identical requests have the same effect as one request.
HTTP Status Codes
Success (2xx):
- 200 OK, 201 Created, 204 No Content
Client Errors (4xx):
- 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found
- 409 Conflict, 422 Unprocessable Entity, 429 Too Many Requests
Server Errors (5xx):
- 500 Internal Server Error, 503 Service Unavailable
For complete status code guide, see references/rest-design.md
API Style Selection
Decision Matrix
| Factor | REST | GraphQL | WebSocket | Message Queue |
|---|---|---|---|---|
| Public API | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | ⭐ |
| Complex Data | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐ |
| Caching | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐ | ⭐ |
| Real-time | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Simplicity | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
Quick Selection
- Public API, CRUD operations → REST
- Complex data, flexible queries → GraphQL
- Real-time, bidirectional → WebSockets
- Event-driven, microservices → Message Queue
For detailed protocol selection, see references/protocol-selection.md
API Versioning
URL Path Versioning (Recommended)
https://api.example.com/v1/users
https://api.example.com/v2/users
Pros: Explicit, easy to implement and test Cons: Maintenance overhead
Alternative Strategies
- Header-Based:
Accept-Version: v1 - Media Type:
Accept: application/vnd.example.v1+json - Query Parameter:
?version=1(not recommended)
Breaking Change Management
Timeline:
- Month 0: Announce deprecation
- Months 1-3: Migration period
- Months 4-6: Deprecation warnings
- Month 6: Sunset (return 410 Gone)
Include deprecation headers:
Deprecation: true
Sunset: Sat, 31 Dec 2025 23:59:59 GMT
Link: </api/v2/users>; rel="successor-version"
For complete versioning guide, see references/versioning-strategies.md
Error Response Standards
RFC 7807 Problem Details (Recommended)
{
"type": "https://api.example.com/errors/validation",
"title": "Validation Error",
"status": 400,
"detail": "One or more fields failed validation",
"errors": [
{
"field": "email",
"message": "Must be a valid email address",
"code": "INVALID_EMAIL"
}
]
}
Content-Type: application/problem+json
For complete error patterns, see references/error-handling.md
Pagination Patterns
Strategy Selection
| Scenario | Strategy | Why |
|---|---|---|
| Small datasets (<1000) | Offset-based | Simple, page numbers |
| Large datasets (>10K) | Cursor-based | Efficient, handles writes |
| Sorted data | Keyset | Consistent results |
| Real-time feeds | Cursor-based | Handles new items |
Offset-Based (Simple)
GET /users?limit=20&offset=40
Response includes: limit, offset, total, currentPage
Cursor-Based (Scalable)
GET /users?limit=20&cursor=eyJpZCI6MTIzfQ==
Cursor is base64-encoded JSON with position information.
Response includes: nextCursor, hasNext
For implementation details, see references/pagination-patterns.md
Rate Limiting
Token Bucket Algorithm
- Each user has bucket with tokens
- Each request consumes 1 token
- Tokens refill at constant rate
- Empty bucket rejects request
Rate Limit Headers
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 73
X-RateLimit-Reset: 1672531200
When exceeded (429):
Retry-After: 3600
Strategies
- Per User: 100 requests/hour
- Per API Key: 1000 requests/hour
- Per IP: 50 requests/hour (unauthenticated)
- Tiered: Free (100/hr), Pro (1000/hr), Enterprise (10000/hr)
For implementation patterns, see references/rate-limiting.md
API Security Design
OAuth 2.0 Flows
Authorization Code Flow (Web Apps):
- Redirect user to authorization server
- User grants permission
- Exchange code for access token
- Use token for API requests
Client Credentials Flow (Service-to-Service):
- Authenticate with client ID and secret
- Receive access token
- Use token for API requests
Scope-Based Authorization
Define granular permissions:
read:users - Read user data
write:users - Create/update users
delete:users - Delete users
admin:* - Full admin access
API Key Management
Use header-based keys:
X-API-Key: sk_live_abc123xyz456
Best practices:
- Prefix with environment:
sk_live_*,sk_test_* - Store hashed keys only
- Support key rotation
- Track last-used timestamp
For complete security patterns, see references/authentication.md
OpenAPI Specification
Basic Structure
openapi: 3.1.0
info:
title: User Management API
version: 2.0.0
paths:
/users:
get:
summary: List users
parameters:
- name: limit
in: query
schema:
type: integer
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/UserList'
OpenAPI enables:
- Code generation (server stubs, client SDKs)
- Validation (request/response checking)
- Mock servers (testing against spec)
- Documentation (interactive docs)
For complete OpenAPI examples, see examples/openapi/
AsyncAPI Specification
Event-Driven APIs
AsyncAPI defines message-based APIs (WebSockets, Kafka, MQTT):
asyncapi: 3.0.0
info:
title: Order Events API
channels:
orders/created:
address: orders.created
messages:
orderCreated:
payload:
type: object
properties:
orderId:
type: string
For AsyncAPI examples, see examples/asyncapi/
GraphQL Design
Schema Structure
type User {
id: ID!
username: String!
posts(limit: Int): [Post!]!
}
type Query {
user(id: ID!): User
users(limit: Int): [User!]!
}
type Mutation {
createUser(input: CreateUserInput!): User!
}
N+1 Problem Solution
Use DataLoader to batch requests:
const userLoader = new DataLoader(async (userIds) => {
// Single query for all users
const users = await db.users.findByIds(userIds);
return userIds.map(id => users.find(u => u.id === id));
});
For GraphQL patterns, see references/graphql-design.md
Quick Reference Tables
Pagination Strategy Selection
| Scenario | Strategy |
|---|---|
| Small datasets | Offset-based |
| Large datasets | Cursor-based |
| Sorted data | Keyset |
| Real-time feeds | Cursor-based |
Versioning Strategy Selection
| Factor | URL Path | Header | Media Type |
|---|---|---|---|
| Visibility | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐ |
| Simplicity | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
| Best For | Most APIs | Internal APIs | Content negotiation |
Integration with Other Skills
- api-patterns: Implement API designs in Express, FastAPI, Go
- auth-security: Implement OAuth2, JWT, session management
- database-design: Design database schemas for API resources
- testing-strategies: API testing (integration, contract, load)
- deploying-applications: Deploy and scale APIs
- observability: Monitor API performance and errors
Additional Resources
Detailed guidance:
- references/rest-design.md - RESTful patterns and best practices
- references/graphql-design.md - GraphQL schema and resolver patterns
- references/versioning-strategies.md - Comprehensive versioning guide
- references/error-handling.md - RFC 7807 implementation details
- references/pagination-patterns.md - Pagination implementation patterns
- references/rate-limiting.md - Rate limiting algorithms and strategies
- references/authentication.md - OAuth2, API keys, scopes
- references/protocol-selection.md - Choosing the right API style
Working examples:
- examples/openapi/ - Complete OpenAPI 3.1 specifications
- examples/asyncapi/ - Event-driven API specifications
- examples/graphql/ - GraphQL schemas and patterns
Validation and tooling:
- scripts/validate-openapi.sh - Validate OpenAPI specifications
Source
git clone https://github.com/ancoleman/ai-design-components/blob/main/skills/designing-apis/SKILL.mdView on GitHub Overview
Design well-structured APIs using REST, GraphQL, or event-driven patterns. This skill emphasizes resource design, versioning, error handling, pagination, rate limiting, and security to keep APIs maintainable as teams evolve.
How This Skill Works
Choose the right protocol (REST, GraphQL, or event-driven) based on data needs, model resources or schemas, and apply consistent error formats, pagination, and security. Document designs with OpenAPI for REST and AsyncAPI for events, and decide on a versioning strategy (path, headers, or media types).
When to Use It
- Designing a new REST, GraphQL, or event-driven API
- Establishing API design standards for a team or organization
- Planning API versioning and breaking change management
- Defining error response formats and HTTP status usage
- Implementing pagination, filtering, and rate limiting patterns
Quick Start
- Step 1: Define resources and endpoints (or GraphQL types) for your domain.
- Step 2: Pick a protocol and versioning approach; outline security (OAuth2, API keys).
- Step 3: Create OpenAPI/AsyncAPI specs and define error formats, pagination, and rate limits.
Best Practices
- Name resources with nouns and nest relationships sensibly (limit depth to 2-3 levels).
- Standardize error payloads and HTTP status codes across all APIs.
- Version APIs clearly (path-based v1/v2) and plan deprecation.
- Document with OpenAPI for REST and AsyncAPI for event-driven APIs.
- Choose the right protocol per use case and implement robust security (OAuth2, API keys).
Example Use Cases
- Designing a new REST API for user and post resources with clear endpoints and pagination.
- Evolving an existing API with versioned endpoints and a deprecation plan.
- Creating a GraphQL schema for a product catalog with complex relationships.
- Implementing event-driven API patterns using a message broker for order processing.
- Publishing API design standards for a multi-team organization and generating OpenAPI specs.