API Design
When to use this skill
-
Designing new REST APIs
-
Creating GraphQL schemas
-
Refactoring API endpoints
-
Documenting API specifications
-
API versioning strategies
-
Defining data models and relationships
Instructions
Step 1: Define API requirements
-
Identify resources and entities
-
Define relationships between entities
-
Specify operations (CRUD, custom actions)
-
Plan authentication/authorization
-
Consider pagination, filtering, sorting
Step 2: Design REST API
Resource naming:
-
Use nouns, not verbs: /users not /getUsers
-
Use plural names: /users/{id}
-
Nest resources logically: /users/{id}/posts
-
Keep URLs short and intuitive
HTTP methods:
-
GET : Retrieve resources (idempotent)
-
POST : Create new resources
-
PUT : Replace entire resource
-
PATCH : Partial update
-
DELETE : Remove resources (idempotent)
Response codes:
-
200 OK : Success with response body
-
201 Created : Resource created successfully
-
204 No Content : Success with no response body
-
400 Bad Request : Invalid input
-
401 Unauthorized : Authentication required
-
403 Forbidden : No permission
-
404 Not Found : Resource doesn't exist
-
409 Conflict : Resource conflict
-
422 Unprocessable Entity : Validation failed
-
500 Internal Server Error : Server error
Example REST endpoint:
GET /api/v1/users # List users GET /api/v1/users/{id} # Get user POST /api/v1/users # Create user PUT /api/v1/users/{id} # Update user PATCH /api/v1/users/{id} # Partial update DELETE /api/v1/users/{id} # Delete user
Step 3: Request/Response format
Request example:
POST /api/v1/users Content-Type: application/json
{ "name": "John Doe", "email": "john@example.com", "role": "admin" }
Response example:
HTTP/1.1 201 Created Content-Type: application/json Location: /api/v1/users/123
{ "id": 123, "name": "John Doe", "email": "john@example.com", "role": "admin", "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-15T10:30:00Z" }
Step 4: Error handling
Error response format:
{ "error": { "code": "VALIDATION_ERROR", "message": "Invalid input provided", "details": [ { "field": "email", "message": "Invalid email format" } ] } }
Step 5: Pagination
Query parameters:
GET /api/v1/users?page=2&limit=20&sort=-created_at&filter=role:admin
Response with pagination:
{ "data": [...], "pagination": { "page": 2, "limit": 20, "total": 100, "pages": 5 }, "links": { "self": "/api/v1/users?page=2&limit=20", "first": "/api/v1/users?page=1&limit=20", "prev": "/api/v1/users?page=1&limit=20", "next": "/api/v1/users?page=3&limit=20", "last": "/api/v1/users?page=5&limit=20" } }
Step 6: Authentication
Options:
-
JWT (JSON Web Tokens)
-
OAuth 2.0
-
API Keys
-
Session-based
Example with JWT:
GET /api/v1/users Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Step 7: Versioning
URL versioning (recommended):
/api/v1/users /api/v2/users
Header versioning:
GET /api/users Accept: application/vnd.api+json; version=1
Step 8: Documentation
Create OpenAPI 3.0 specification:
openapi: 3.0.0 info: title: User Management API version: 1.0.0 description: API for managing users servers:
- url: https://api.example.com/v1 paths: /users: get: summary: List users parameters: - name: page in: query schema: type: integer default: 1 - name: limit in: query schema: type: integer default: 20 responses: '200': description: Successful response content: application/json: schema: type: object properties: data: type: array items: $ref: '#/components/schemas/User' post: summary: Create user requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UserCreate' responses: '201': description: User created content: application/json: schema: $ref: '#/components/schemas/User' components: schemas: User: type: object properties: id: type: integer name: type: string email: type: string format: email created_at: type: string format: date-time UserCreate: type: object required: - name - email properties: name: type: string email: type: string format: email
Best practices
-
Consistency: Use consistent naming, structure, and patterns
-
Versioning: Always version your APIs from the start
-
Security: Implement authentication and authorization
-
Validation: Validate all inputs on the server side
-
Rate limiting: Protect against abuse
-
Caching: Use ETags and Cache-Control headers
-
CORS: Configure properly for web clients
-
Documentation: Keep docs up-to-date with code
-
Testing: Test all endpoints thoroughly
-
Monitoring: Log requests and track performance
Common patterns
Filtering:
GET /api/v1/users?role=admin&status=active
Sorting:
GET /api/v1/users?sort=-created_at,name
Field selection:
GET /api/v1/users?fields=id,name,email
Batch operations:
POST /api/v1/users/batch { "operations": [ {"action": "create", "data": {...}}, {"action": "update", "id": 123, "data": {...}} ] }
GraphQL alternative
If REST doesn't fit, consider GraphQL:
type User { id: ID! name: String! email: String! posts: [Post!]! createdAt: DateTime! }
type Query { users(page: Int, limit: Int): [User!]! user(id: ID!): User }
type Mutation { createUser(input: CreateUserInput!): User! updateUser(id: ID!, input: UpdateUserInput!): User! deleteUser(id: ID!): Boolean! }
References
-
OpenAPI Specification
-
REST API Tutorial
-
GraphQL Best Practices
-
HTTP Status Codes
Examples
Example 1: Basic usage
Example 2: Advanced usage