API Design and REST Principles
Design APIs that are predictable, scalable and easy to integrate with proper HTTP semantics and versioning.
Before you start
Who is this for?
For developers, DevOps engineers and architects who build or integrate APIs.
Prerequisites
- Understanding of HTTP basics
- Familiarity with JSON
- Basic networking concepts
What you'll be able to do
- Apply REST principles correctly
- Choose appropriate HTTP methods and status codes
- Design consistent API endpoints
- Version APIs responsibly
- Implement rate limiting and caching
- Secure APIs with authentication
Practical outcome
You can design a REST API that developers find intuitive to use and that scales reliably.
APIs are the contracts between services. Good API design makes integration seamless; poor design causes frustration and bugs. REST (Representational State Transfer) is the most common style for web APIs.
1. REST Principles
Section titled “1. REST Principles”REST is an architectural style, not a strict protocol. It emphasizes:
- Client-Server: Clear separation of concerns.
- Stateless: Each request contains all information needed. Server does not store client context.
- Uniform Interface: Consistent resource identification and manipulation.
- Cacheable: Responses should indicate if they can be cached.
A truly RESTful API is more than using HTTP correctly; it follows these principles.
2. Resources and Endpoints
Section titled “2. Resources and Endpoints”Resources are nouns (things), not verbs (actions). Endpoints identify resources; HTTP methods perform actions on them.
✓ Good: /users, /orders, /products✗ Bad: /getUserList, /createOrder, /deleteProduct
✓ Good: GET /users/5✗ Bad: GET /getUser/5
✓ Good: POST /orders✗ Bad: POST /createOrderEndpoint structure typically follows:
/v1/resource/v1/resource/{id}/v1/resource/{id}/subresource3. HTTP Methods: Semantics Matter
Section titled “3. HTTP Methods: Semantics Matter”Each method has a specific meaning. Using the wrong method confuses clients and can cause caching issues.
| Method | Semantics | Idempotent | Safe | Example |
|---|---|---|---|---|
| GET | Retrieve resource | Yes | Yes | GET /users/5 returns user |
| POST | Create new resource | No | No | POST /users creates user |
| PUT | Replace entire resource | Yes | No | PUT /users/5 replaces user |
| PATCH | Partial update | Not guaranteed | No | PATCH /users/5 updates name only |
| DELETE | Remove resource | Yes | No | DELETE /users/5 deletes user |
Idempotent means repeating the same request has the same intended effect as making it once. Safe means it does not request a state change. GET is safe and idempotent; PUT and DELETE are idempotent by HTTP semantics. PATCH is not guaranteed idempotent, though an API can define a particular patch operation so that repeating it has the same effect.
4. Status Codes: Communicate Intent
Section titled “4. Status Codes: Communicate Intent”The response status communicates success or failure. Clients should handle status codes, not guess from response content.
| Range | Meaning | Examples |
|---|---|---|
| 2xx | Success | 200 OK, 201 Created, 204 No Content |
| 3xx | Redirect | 301 Moved Permanently, 304 Not Modified |
| 4xx | Client error | 400 Bad Request, 401 Unauthorized, 404 Not Found |
| 5xx | Server error | 500 Internal Server Error, 503 Service Unavailable |
Common mistakes:
- Always returning 200, even on error. Clients cannot detect problems.
- Returning 500 for validation errors (should be 400).
- Returning 200 for “resource not found” (should be 404).
5. Request and Response Format
Section titled “5. Request and Response Format”APIs typically use JSON. Include version in the header or URL.
Request:
POST /v1/usersContent-Type: application/jsonAuthorization: Bearer token123
{ "name": "Alice", "email": "alice@example.com", "role": "admin"}Response (success):
HTTP/1.1 201 CreatedContent-Type: application/json
{ "id": 42, "name": "Alice", "email": "alice@example.com", "role": "admin", "created_at": "2026-09-18T08:41:00Z"}Response (error):
HTTP/1.1 400 Bad RequestContent-Type: application/json
{ "error": "validation_error", "message": "Email format is invalid", "details": { "field": "email", "value": "alice@invalid" }}6. Pagination
Section titled “6. Pagination”Large result sets must be paginated to prevent loading entire databases.
GET /v1/orders?limit=20&offset=0GET /v1/orders?page=1&page_size=20GET /v1/orders?cursor=abc123&limit=20Response includes metadata:
{ "data": [...], "pagination": { "total": 1000, "limit": 20, "offset": 0, "pages": 50 }}Cursor-based pagination is best for large datasets because offsets become slow as data grows.
7. API Versioning
Section titled “7. API Versioning”APIs change. Versioning allows clients to continue using old versions while you develop new ones.
Strategies:
- URL path:
/v1/users,/v2/users - Header:
Accept: application/json; version=2 - Query parameter:
/users?version=2
URL path is most common and explicit. Never remove old versions abruptly; deprecate gradually with warnings.
8. Rate Limiting and Caching
Section titled “8. Rate Limiting and Caching”Rate limiting prevents abuse. Caching reduces server load.
HTTP/1.1 200 OKX-RateLimit-Limit: 1000X-RateLimit-Remaining: 999X-RateLimit-Reset: 1695022860Cache-Control: public, max-age=3600ETag: "abc123"
{ "data": [...]}Clients check X-RateLimit-Remaining and back off before hitting the limit. Cache-Control tells clients how long to cache. ETag enables conditional requests (If-None-Match).
9. Security
Section titled “9. Security”APIs often expose sensitive data. Security is critical.
- Authentication: Only authenticated users access the API. Use OAuth2, API keys or JWT.
- Authorization: Authenticated users can only access their own data. Use role-based or attribute-based access control.
- Encryption: Use HTTPS everywhere. Sensitive data in request bodies and responses must be encrypted.
- Input validation: Reject invalid input before processing.
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...Never store plain-text passwords or API keys. Use hashing and secrets managers.
10. Common Mistakes
Section titled “10. Common Mistakes”- Inconsistent endpoint naming. Mix of singular/plural,
/getvs GET. - Wrong HTTP methods. POST when GET should be used.
- Returning 200 on errors. Status codes communicate intent.
- No pagination. Large queries returning millions of rows.
- No API documentation. Developers have to reverse-engineer your API.
- Breaking changes without versioning. Existing clients break.
- No rate limiting. Bots abuse the API.
- Storing secrets in logs. API keys and tokens exposed.
What You Should Be Able to Do Now
Section titled “What You Should Be Able to Do Now”- Design RESTful endpoints following HTTP semantics;
- Choose appropriate status codes and error formats;
- Implement pagination, versioning and rate limiting;
- Secure APIs with authentication and authorization;