RESTful API Design Principles: Building APIs
That Scale
Introduction
A well-designed API is the backbone of modern software architecture. This
guide distills battle-tested principles for designing RESTful APIs that are
intuitive, maintainable, and performant.
1. Resource Naming Conventions
Rules
Use nouns, not verbs: /users not /getUsers
Use plural forms: /articles not /article
Use kebab-case for multi-word resources: /user-profiles
Nest resources to show relationships: /users/42/orders
Anti-Patterns to Avoid
❌ GET /getAllUsers
❌ POST /createNewOrder
❌ GET /user/delete/42
✅ GET /users
✅ POST /orders
✅ DELETE /users/42
2. HTTP Methods and Status Codes
Method Semantics
Method Purpose Idempotent Safe
GET Retrieve Yes Yes
resource(s)
POST Create a new No No
resource
PUT Replace entire Yes No
resource
PATCH Partial update No No
DELETE Remove a Yes No
resource
Essential Status Codes
Code Meaning When to Use
200 OK Successful GET,
PUT, PATCH
201 Created Successful POST
204 No Content Successful DELETE
400 Bad Request Validation errors
401 Unauthorized Missing/invalid
authentication
403 Forbidden Authenticated but
insufficient
permissions
404 Not Found Resource doesn’t
exist
409 Conflict Duplicate or state
conflict
429 Too Many Requests Rate limit exceeded
500 Internal Server Unhandled server
Error failure
3. Pagination, Filtering, and Sorting
Cursor-Based Pagination (Recommended)
GET /articles?cursor=eyJpZCI6MTAwfQ&limit=20
Response:
{
"data": [...],
"pagination": {
"next_cursor": "eyJpZCI6MTIwfQ",
"has_more": true
}
}
Filtering and Sorting
GET /products?category=electronics&price_min=100&sort=-created_at
Use - prefix for descending order.
4. Versioning Strategies
Strategy Example Pros Cons
URL path /v2/users Simple, URL
explicit pollution
Header Accept: Clean URLs Less
application/[Link] discoverable
i+json;v=2
Query param /users?version=2 Easy to test Caching
issues
Recommendation: Use URL path versioning for public APIs due to simplicity
and tooling support.
5. Error Response Format
Standardize error responses across your entire API:
{
"error": {
"code": "VALIDATION_FAILED",
"message": "Request validation failed",
"details": [
{
"field": "email",
"issue": "Must be a valid email address"
},
{
"field": "age",
"issue": "Must be at least 18"
}
],
"request_id": "req_abc123"
}
}
Always include a request_id for debugging and support.
6. Rate Limiting and Throttling
Include rate limit headers in every response:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 742
X-RateLimit-Reset: 1719504000
Implement tiered rate limits: - Anonymous: 60 requests/hour -
Authenticated: 1000 requests/hour - Premium: 10000 requests/hour
7. Authentication and Authorization
Token-Based Auth Flow
1. Client sends credentials to /auth/token
2. Server returns a short-lived access token + refresh token
3. Client includes Authorization: Bearer <token> on subsequent
requests
4. Client uses refresh token to obtain new access tokens
Security Headers
Strict-Transport-Security: max-age=31536000
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Conclusion
Great APIs are designed for the consumer. Prioritize consistency, provide
comprehensive documentation, and version thoughtfully. An API is a contract
— treat breaking changes with the same gravity as database migrations.
© 2026 — Software Architecture Series