Awesome-omni-skill API Designer
Design REST and GraphQL APIs. Use when creating backend APIs, defining API contracts, or integrating third-party services. Covers endpoint design, authentication, versioning, documentation, and best practices.
git clone https://github.com/diegosouzapw/awesome-omni-skill
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/development/api-designer-daffy0208" ~/.claude/skills/diegosouzapw-awesome-omni-skill-api-designer-73070d && rm -rf "$T"
skills/development/api-designer-daffy0208/SKILL.mdAPI Designer
Design robust, scalable, and developer-friendly APIs.
Core Principles
1. Developer Experience First
- Clear, predictable naming conventions
- Comprehensive documentation
- Helpful error messages
- Consistent patterns across endpoints
2. Design for Evolution
- Versioning strategy from day one
- Backward compatibility
- Deprecation process
- Migration guides for breaking changes
3. Security by Default
- Authentication and authorization
- Rate limiting and throttling
- Input validation and sanitization
- HTTPS only, no exceptions
4. Performance Matters
- Efficient queries and indexing
- Caching strategies
- Pagination for large datasets
- Compression (gzip, brotli)
REST API Design
Resource Naming Conventions
✅ Good (Nouns, plural, hierarchical): GET /users # List all users GET /users/123 # Get specific user POST /users # Create user PUT /users/123 # Replace user PATCH /users/123 # Update user DELETE /users/123 # Delete user GET /users/123/posts # User's posts (nested) GET /users/123/posts/456 # Specific post ❌ Bad (Verbs, inconsistent, unclear): GET /getUsers POST /createUser GET /user-list GET /UserData?id=123
HTTP Methods & Semantics
| Method | Purpose | Idempotent | Safe | Request Body | Response Body |
|---|---|---|---|---|---|
| GET | Retrieve data | Yes | Yes | No | Yes |
| POST | Create resource | No | No | Yes | Yes (created) |
| PUT | Replace resource | Yes | No | Yes | Yes (optional) |
| PATCH | Partial update | No | No | Yes | Yes (optional) |
| DELETE | Remove resource | Yes | No | No | No (204) or Yes |
Idempotent: Multiple identical requests have same effect as single request Safe: Request doesn't modify server state
HTTP Status Codes
Success (2xx):
- Successful GET, PUT, PATCH, DELETE200 OK
- Successful POST, includes201 Created
headerLocation
- Successful request, no response body (often DELETE)204 No Content
Client Errors (4xx):
- Invalid syntax, validation error400 Bad Request
- Authentication required or failed401 Unauthorized
- Authenticated but lacks permission403 Forbidden
- Resource doesn't exist404 Not Found
- Request conflicts with current state409 Conflict
- Validation error (semantic)422 Unprocessable Entity
- Rate limit exceeded429 Too Many Requests
Server Errors (5xx):
- Generic server error500 Internal Server Error
- Upstream service error502 Bad Gateway
- Temporary unavailability503 Service Unavailable
- Upstream timeout504 Gateway Timeout
Response Format Standards
Success Response:
{ "data": { "id": "123", "type": "user", "attributes": { "name": "John Doe", "email": "john@example.com", "created_at": "2025-01-15T10:30:00Z" } } }
Error Response:
{ "error": { "code": "VALIDATION_ERROR", "message": "Request validation failed", "details": [ { "field": "email", "code": "REQUIRED", "message": "Email is required" }, { "field": "age", "code": "OUT_OF_RANGE", "message": "Age must be between 18 and 120" } ], "request_id": "req_abc123", "documentation_url": "https://api.example.com/docs/errors/validation" } }
List Response with Pagination:
{ "data": [...], "pagination": { "cursor": "eyJpZCI6MTIzfQ==", "has_more": true, "total_count": 1000 }, "links": { "next": "/users?cursor=eyJpZCI6MTIzfQ==&limit=20", "prev": "/users?cursor=eyJpZCI6MTAwfQ==&limit=20" } }
Pagination Strategies
Cursor-based (Recommended):
GET /users?cursor=abc123&limit=20 Pros: Consistent results, efficient, handles real-time data Cons: Can't jump to arbitrary page Use when: Large datasets, real-time data, performance critical
Offset-based:
GET /users?page=1&per_page=20 GET /users?offset=0&limit=20 Pros: Simple, can jump to any page Cons: Inconsistent with concurrent writes, inefficient at scale Use when: Small datasets, admin interfaces, simple use cases
Filtering, Sorting, and Search
Filtering:
GET /users?status=active&role=admin&created_after=2025-01-01
Sorting:
GET /users?sort=-created_at,name # Descending created_at, then ascending name
Search:
GET /users?q=john&fields=name,email # Search across specified fields
Authentication & Authorization
JWT Bearer Token (Recommended for SPAs):
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... Pros: Stateless, includes user claims, works across domains Cons: Can't revoke until expiry, larger payload
API Keys (for service-to-service):
X-API-Key: sk_live_abc123... Pros: Simple, easy to rotate, per-service keys Cons: No user context, must be kept secret
OAuth 2.0 (for third-party access):
Authorization: Bearer access_token Pros: Delegated auth, scoped permissions, industry standard Cons: Complex setup, requires OAuth server
Basic Auth (only for internal/admin tools):
Authorization: Basic base64(username:password) Pros: Simple, built-in to HTTP Cons: Credentials in every request, must use HTTPS
Rate Limiting
Standard Headers:
X-RateLimit-Limit: 1000 # Max requests per window X-RateLimit-Remaining: 999 # Requests left X-RateLimit-Reset: 1640995200 # Unix timestamp when limit resets Retry-After: 60 # Seconds to wait (on 429)
Common Strategies:
- Fixed window: 1000 requests per hour
- Sliding window: 1000 requests per rolling hour
- Token bucket: Burst allowance with refill rate
- Per-user, per-IP, or per-API-key limits
Versioning Strategies
URL Versioning (Recommended):
/v1/users /v2/users Pros: Explicit, easy to route, clear in logs Cons: URL pollution, harder to evolve incrementally
Header Versioning:
Accept: application/vnd.myapp.v2+json API-Version: 2 Pros: Clean URLs, follows REST principles Cons: Less visible, harder to test in browser
Best Practices:
- Start with v1, not v0
- Only increment for breaking changes
- Support N and N-1 versions simultaneously
- Provide migration guides
- Announce deprecation 6-12 months ahead
GraphQL API Design
Schema Design
type User { id: ID! name: String! email: String! posts(first: Int, after: String): PostConnection! createdAt: DateTime! } type PostConnection { edges: [PostEdge!]! pageInfo: PageInfo! } type PostEdge { node: Post! cursor: String! } type PageInfo { hasNextPage: Boolean! endCursor: String } type Query { user(id: ID!): User users(first: Int, after: String): UserConnection! } type Mutation { createUser(input: CreateUserInput!): CreateUserPayload! updateUser(id: ID!, input: UpdateUserInput!): UpdateUserPayload! } input CreateUserInput { name: String! email: String! } type CreateUserPayload { user: User errors: [Error!] }
GraphQL Best Practices
1. Use Relay Connection Pattern for Pagination:
query { users(first: 10, after: "cursor") { edges { node { id name } cursor } pageInfo { hasNextPage endCursor } } }
2. Input Types for Mutations:
# ✅ Good: Input type + payload mutation { createUser(input: { name: "John", email: "john@example.com" }) { user { id name } errors { field message } } } # ❌ Bad: Flat arguments mutation { createUser(name: "John", email: "john@example.com") { id name } }
3. Error Handling:
type Mutation { createUser(input: CreateUserInput!): CreateUserPayload! } type CreateUserPayload { user: User # Null if errors errors: [Error!] # Field-level errors } type Error { field: String! code: String! message: String! }
REST vs GraphQL Decision
Use REST when:
- Simple CRUD operations
- Caching is critical (HTTP caching)
- Public API for third-parties
- File uploads/downloads
- Team unfamiliar with GraphQL
Use GraphQL when:
- Clients need flexible queries
- Reducing over-fetching/under-fetching
- Rapid frontend iteration
- Complex nested data relationships
- Strong typing and schema benefits
API Documentation
OpenAPI/Swagger Specification
openapi: 3.0.0 info: title: User Management API version: 1.0.0 description: API for managing users and posts servers: - url: https://api.example.com/v1 paths: /users: get: summary: List users parameters: - name: page in: query schema: type: integer default: 1 - name: per_page in: query schema: type: integer default: 20 maximum: 100 responses: '200': description: Success content: application/json: schema: $ref: '#/components/schemas/UserList' '401': $ref: '#/components/responses/Unauthorized' post: summary: Create user requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateUserInput' responses: '201': description: User created content: application/json: schema: $ref: '#/components/schemas/User' components: schemas: User: type: object properties: id: type: string name: type: string email: type: string format: email securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT
Documentation Best Practices
- ✅ Include request/response examples
- ✅ Document all error codes
- ✅ Provide authentication guides
- ✅ Interactive API playground (Swagger UI, GraphQL Playground)
- ✅ Code examples in multiple languages
- ✅ Rate limit information
- ✅ Changelog for API updates
Security Checklist
- HTTPS only (redirect HTTP → HTTPS)
- Authentication required for protected endpoints
- Authorization checks (user can only access own data)
- Input validation (schema validation, sanitization)
- Rate limiting per user/IP
- CORS configuration (whitelist origins)
- SQL injection prevention (parameterized queries)
- No sensitive data in URLs (use headers/body)
- Audit logging for sensitive operations
- API keys rotatable and revocable
Related Resources
Related Skills:
- For consuming APIs from frontendfrontend-builder
- For API hosting decisionsdeployment-advisor
- For API performance tuningperformance-optimizer
Related Patterns:
- REST vs GraphQL decisionsMETA/DECISION-FRAMEWORK.md
- API gateway architecture (when created)STANDARDS/architecture-patterns/api-gateway-pattern.md
Related Playbooks:
- API deployment procedure (when created)PLAYBOOKS/deploy-api.md
- API versioning workflow (when created)PLAYBOOKS/version-api.md