api-development-expert
Api Development Expert
When designing REST APIs, follow these core architectural principles:
Resource-Oriented Design
- Use nouns for resources (plural form):
/users,/products,/orders - Avoid verbs in URIs: ❌
/getUsers,/createProduct - Structure hierarchically:
/users/{userId}/orders(orders belonging to a user) - Use lowercase with hyphens:
/product-detailsnot/productdetails - No trailing slashes:
/usersnot/users/
HTTP Methods (Verbs with Purpose)
GET- Retrieve resources (idempotent & safe, no side effects)POST- Create new resources (not idempotent, returns 201 Created with Location header)PUT- Replace entire resource or upsert (idempotent)PATCH- Partial update (not idempotent, useapplication/json-patch+json)DELETE- Remove resource (idempotent, returns 204 No Content or 200 OK)
Query Parameters for Filtering, Sorting, and Pagination
- Filtering:
/products?category=electronics&price_gt=100 - Sorting:
/products?sort_by=price&order=desc - Pagination:
/products?page=2&limit=10- Use offset-based (simple but inefficient for deep pages) or cursor-based (efficient for large datasets)
API Versioning Strategies
Choose one and stick to it:
- URI Versioning (Most common):
/v1/users,/api/v2/products- Simple for clients, but makes URIs less clean
- Header Versioning:
Accept: application/vnd.myapi.v1+json- Cleaner URIs, but slightly complex for caching and some clients
- Content Negotiation: Use Accept header to specify desired media type and version
OpenAPI/Swagger Specification
Use OpenAPI 3.0+ to define your API specification:
Benefits:
- Machine-readable API specification
- Auto-generates interactive documentation portals
- Client SDK generation
- Request/response schema validation
- IDE and API tool auto-validation
Define schemas for:
- Request parameters (required fields, allowed values, data types)
- Response structures
- Error responses
- Authentication methods
- Enum lists for restricted values
Example: Define validation rules so invalid requests are caught before reaching your backend
Rate Limiting Patterns
Protect against abuse and ensure fair usage:
Implementation strategies:
- Use
429 Too Many Requestsstatus code - Return rate limit headers:
X-RateLimit-Limit: 1000X-RateLimit-Remaining: 999X-RateLimit-Reset: 1640000000
- Common patterns:
- Fixed window: Simple but allows bursts at boundaries
- Sliding window: More accurate, prevents boundary gaming
- Token bucket: Allows controlled bursts
- Leaky bucket: Smooths out traffic
Error Handling Standards
Consistent Error Response Structure:
{
"error": {
"code": "validation_error",
"message": "Input validation failed.",
"details": [{ "field": "email", "message": "Invalid email format." }]
}
}
Use Appropriate HTTP Status Codes:
2xx Success: 200 OK, 201 Created, 204 No Content
3xx Redirection: 301 Moved Permanently, 304 Not Modified
4xx Client Error:
400 Bad Request- General client error401 Unauthorized- Authentication missing/failed403 Forbidden- Authenticated but no permission404 Not Found- Resource doesn't exist405 Method Not Allowed- Invalid HTTP method409 Conflict- Resource already exists422 Unprocessable Entity- Semantic validation error429 Too Many Requests- Rate limiting
5xx Server Error:
500 Internal Server Error- Generic server error503 Service Unavailable- Service temporarily down
Provide machine-readable codes AND human-readable messages
Authentication Patterns
OAuth 2.1 (Industry standard for delegated authorization)
- Mandatory PKCE for all authorization code flows
- Authorization Code + PKCE flow for SPAs, mobile, and web apps
- Removed flows: Implicit grant and Resource Owner Password Credentials (security risks)
- Exact redirect URI matching (no wildcards)
- Never send bearer tokens in query strings (use Authorization header)
- Implement refresh token rotation or sender-constrained tokens
JWT (JSON Web Tokens) for stateless authentication:
- Short expiry times (≤15 minutes for access tokens)
- Use refresh tokens for long-lived sessions
- Include claims for authorization decisions
- Validate signature, expiry, and issuer
API Keys for simpler integrations:
- Use for service-to-service authentication
- Rotate regularly
- Never expose in client-side code
- Implement rate limiting per key
Performance & Caching
HTTP Caching Headers:
Cache-Control: max-age=3600- Cache for 1 hourETag- Entity tag for conditional requestsExpires- Absolute expiration time304 Not Modified- Return for unchanged resources
Caching strategies:
- Client-side caching (browser cache)
- Proxy/CDN caching (intermediate caches)
- Server-side caching (database query cache, object cache)
Optimization techniques:
- Compression: Use GZIP for large responses
- Pagination: Return only needed data
- Field selection: Allow clients to request specific fields (
?fields=id,name) - Async operations: For long-running tasks, return
202 Acceptedwith status endpoint
API Documentation Best Practices
Comprehensive documentation must include:
- Overview and getting started guide
- Authentication and authorization details
- Endpoint descriptions with HTTP methods
- Request parameters and body schemas
- Response structures with examples
- Error codes and messages
- Rate limits and usage policies
- SDKs and client libraries
- Changelog for version updates
Use tools:
- Swagger UI / OpenAPI for interactive docs
- Postman collections for testing
- Code examples in multiple languages
OpenAPI 3.1 (2026 Best Practice)
Upgrade from OpenAPI 3.0 to 3.1 for full JSON Schema 2020-12 compliance:
Key differences from 3.0:
| Feature | OpenAPI 3.0 | OpenAPI 3.1 |
|---|---|---|
| JSON Schema compliance | Subset + extensions | Full JSON Schema 2020-12 |
| Nullable fields | nullable: true |
type: ["string", "null"] |
| Webhooks | Not supported | webhooks object at root |
$schema declaration |
Not allowed | Allowed at document root |
example vs examples |
Both allowed together | Mutually exclusive |
OpenAPI 3.1 Webhook definition:
openapi: '3.1.0'
info:
title: My API
version: '1.0.0'
webhooks:
orderCreated:
post:
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/OrderEvent'
responses:
'200':
description: Webhook received successfully
OpenAPI Overlays (v1.1.0, Jan 2026):
Overlays are a companion spec that applies targeted transformations to an OpenAPI document without modifying the source. Use cases:
- Adding environment-specific server URLs
- Injecting partner-specific authentication metadata
- Removing internal endpoints before publishing externally
# overlay.yaml
overlay: '1.0.0'
info:
title: Partner API Overlay
version: '1.0.0'
actions:
- target: "$.paths['/internal/**']"
remove: true
- target: '$.info'
update:
x-partner-id: 'acme-corp'
OpenAPI 3.2 (September 2025) adds:
- Hierarchical tag metadata (
summary,parent,kind) - Streaming-friendly media types with
itemSchema queryHTTP operations andquerystringparameters- OAuth2 device flow and metadata URL support
API Versioning Strategies (2026)
Choose and document your versioning strategy before the first public release:
URI versioning (most common, most explicit):
GET /v1/users
GET /v2/users
- Easy to test, cache, and route
- Consider: version only on breaking changes (additive changes are backward compatible)
Header versioning:
Accept: application/vnd.myapi.v2+json
- Cleaner URIs; slightly harder for browser-based testing
Deprecation lifecycle:
Deprecation: true
Sunset: Sat, 01 Jan 2027 00:00:00 GMT
Link: <https://api.example.com/v2/users>; rel="successor-version"
GraphQL schema evolution (no URI versioning needed):
- Use
@deprecated(reason: "Use newField instead")to phase out fields - Add new fields without removing old ones (additive-only changes)
- Never rename or remove fields from a live schema; deprecate and provide migration path
Rate Limiting — Advanced Patterns (2026)
Standardized headers (IETF draft draft-ietf-httpapi-ratelimit-headers):
RateLimit-Limit: 100
RateLimit-Remaining: 87
RateLimit-Reset: 1
Retry-After: 30
Algorithm comparison:
| Algorithm | Burst Handling | Accuracy | Use Case |
|---|---|---|---|
| Fixed window | Allows boundary bursts | Low | Simple rate caps |
| Sliding window log | No burst | High | Strict SLAs |
| Sliding window counter | Small burst | Medium | General purpose |
| Token bucket | Controlled burst | High | API gateways |
| Leaky bucket | No burst (smoothed) | High | Traffic shaping |
Tiered rate limiting — differentiate by caller type:
rate_limits:
anonymous: 60/hour
authenticated: 1000/hour
premium: 10000/hour
internal_service: unlimited
HATEOAS & Richardson Maturity Model
Design APIs for discoverability — include hypermedia links so clients can navigate state transitions:
Richardson Maturity Levels:
| Level | Description | Example |
|---|---|---|
| 0 | Single endpoint (RPC over HTTP) | POST /api with action field |
| 1 | Resource-based URIs | GET /users/123 |
| 2 | HTTP verbs + status codes | DELETE /users/123 returns 204 |
| 3 | HATEOAS (hypermedia controls) | Response includes _links |
Level 3 example response:
{
"id": "order-42",
"status": "pending",
"total": 99.99,
"_links": {
"self": { "href": "/orders/42" },
"confirm": { "href": "/orders/42/confirm", "method": "POST" },
"cancel": { "href": "/orders/42/cancel", "method": "DELETE" },
"customer": { "href": "/users/7" }
}
}
Level 3 is aspirational; most production APIs operate at Level 2 and selectively add hypermedia links for complex workflows.
GraphQL Federation (2026)
For microservices architectures using GraphQL, federation enables a unified supergraph from distributed subgraphs:
Core concepts:
- Supergraph: The combined schema exposed to clients
- Subgraph: Individual service schemas that each own their type definitions
- Router: Federates queries across subgraphs (Apollo Router, WunderGraph Cosmo)
Best practices:
- One entity (e.g.,
User) can be defined in its owning subgraph and extended in others using@keyand@extends - Schema governance: use a schema registry (Apollo Studio, Cosmo Schema Registry) to validate changes before deployment
- AI/LLM traffic reshaping architecture requirements in 2026 — plan for high-volume, streaming-friendly subgraph operations
Iron Laws
- ALWAYS version your API from day 1 — never introduce breaking changes without a version bump; use URI versioning (
/v1/,/v2/) so clients can migrate on their schedule. - NEVER return 200 OK for errors — use proper HTTP status codes: 400 (bad request), 401 (unauthorized), 403 (forbidden), 404 (not found), 422 (validation failed), 500 (server error).
- ALWAYS document every endpoint in OpenAPI 3.1 — undocumented APIs cannot be safely consumed; OpenAPI 3.1 provides JSON Schema 2020-12 compliance and webhook support.
- NEVER include sensitive data in error responses — stack traces, database schema, and internal file paths are attack vectors; return only machine-readable error codes and safe messages.
- ALWAYS implement rate limiting on all public endpoints — unauthenticated endpoints without rate limiting are DoS vectors; respond with 429 and
Retry-Afterheader.
Anti-Patterns
| Anti-Pattern | Why It Fails | Correct Approach |
|---|---|---|
Verbs in URIs (/getUser, /createOrder) |
Violates REST constraints; HTTP method conveys the verb | Use nouns: /users, /orders with GET/POST |
| No API versioning from day 1 | Breaking changes instantly break all existing clients | URI versioning: /v1/resource from the start |
| Returning 200 OK for errors | Clients can't distinguish success from failure programmatically | Use correct HTTP status codes |
| No rate limiting on public endpoints | DoS vulnerability; single client can exhaust resources | Rate limit with X-RateLimit-* headers + 429 |
| Leaking server internals in errors | Stack traces and DB errors are attack vectors | Return error codes + safe messages only |
| No OpenAPI specification | Clients must guess request/response format | Document all endpoints in OpenAPI 3.1 |
Consolidated Skills
This expert skill consolidates 1 individual skills:
- api-development-expert
Memory Protocol (MANDATORY)
Before starting:
cat .claude/context/memory/learnings.md
After completing: Record any new patterns or exceptions discovered.
ASSUME INTERRUPTION: Your context may reset. If it's not in memory, it didn't happen.