REST API Design Principles and Best Practices

April 5, 2024 (1y ago)

REST API Design Principles and Best Practices

Well-designed APIs are crucial for building scalable applications. Here's how to design REST APIs that developers love.

URL Structure

Use Nouns, Not Verbs

# Bad
GET /getUsers
POST /createUser
DELETE /deleteUser/1
 
# Good
GET /users
POST /users
DELETE /users/1

Use Plural Nouns

# Consistent plural naming
GET /users
GET /users/123
GET /posts
GET /posts/456/comments

Hierarchical Resources

# Nested resources
GET /users/123/posts          # User's posts
GET /posts/456/comments       # Post's comments
GET /users/123/posts/789      # Specific post by user

HTTP Methods

# CRUD Operations
GET     /users          # List all users
GET     /users/123      # Get single user
POST    /users          # Create user
PUT     /users/123      # Update entire user
PATCH   /users/123      # Partial update
DELETE  /users/123      # Delete user

Status Codes

Success Codes

200 OK              # Successful GET, PUT, PATCH
201 Created         # Successful POST (resource created)
204 No Content      # Successful DELETE

Client Error Codes

400 Bad Request     # Invalid request body
401 Unauthorized    # Authentication required
403 Forbidden       # Not enough permissions
404 Not Found       # Resource doesn't exist
409 Conflict        # Resource conflict
422 Unprocessable   # Validation error
429 Too Many Req    # Rate limited

Server Error Codes

500 Internal Error  # Server error
502 Bad Gateway     # Upstream error
503 Unavailable     # Service down

Request & Response

Request Body (Create)

POST /users
Content-Type: application/json
 
{
  "name": "John Doe",
  "email": "john@example.com",
  "role": "user"
}

Response (Success)

HTTP/1.1 201 Created
Content-Type: application/json
 
{
  "data": {
    "id": "123",
    "name": "John Doe",
    "email": "john@example.com",
    "role": "user",
    "createdAt": "2024-04-05T10:30:00Z"
  }
}

Response (Error)

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
 
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "details": [
      {
        "field": "email",
        "message": "Invalid email format"
      }
    ]
  }
}

Pagination

Offset-Based

GET /users?page=2&limit=20
 
Response:
{
  "data": [...],
  "pagination": {
    "page": 2,
    "limit": 20,
    "total": 150,
    "totalPages": 8
  }
}

Cursor-Based (Better for Large Datasets)

GET /users?cursor=eyJpZCI6MTIzfQ&limit=20
 
Response:
{
  "data": [...],
  "pagination": {
    "nextCursor": "eyJpZCI6MTQzfQ",
    "hasMore": true
  }
}

Filtering & Sorting

Query Parameters

# Filtering
GET /users?role=admin&status=active
 
# Sorting
GET /users?sort=createdAt&order=desc
 
# Multiple sorts
GET /users?sort=-createdAt,name
 
# Field selection
GET /users?fields=id,name,email
 
# Search
GET /users?search=john

Versioning

URL Path (Recommended)

GET /v1/users
GET /v2/users

Header

GET /users
Accept: application/vnd.api+json; version=1

Authentication

Bearer Token

GET /users
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

API Key

GET /users
X-API-Key: your-api-key-here

Rate Limiting Headers

HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1712345678

HATEOAS (Optional)

{
  "data": {
    "id": "123",
    "name": "John Doe"
  },
  "links": {
    "self": "/users/123",
    "posts": "/users/123/posts",
    "followers": "/users/123/followers"
  }
}

Best Practices Summary

  1. Use HTTPS - Always encrypt API traffic
  2. Version your API - Plan for breaking changes
  3. Use proper status codes - Be specific about errors
  4. Validate input - Never trust client data
  5. Paginate lists - Prevent large responses
  6. Document everything - Use OpenAPI/Swagger
  7. Rate limit - Protect your API
  8. Use consistent naming - camelCase or snake_case
  9. Include timestamps - createdAt, updatedAt
  10. Support partial updates - Use PATCH wisely

A well-designed API is intuitive, consistent, and a pleasure to work with. Invest time in design before implementation.