DEV Community

Cover image for REST API Design: A Comprehensive Guide
Yukti Sahu
Yukti Sahu

Posted on

REST API Design: A Comprehensive Guide

The Origin Story

REST (Representational State Transfer) was introduced by Roy Fielding in his doctoral dissertation in 2000, building upon the foundational work of Tim Berners-Lee who started the World Wide Web. The web was built on fundamental concepts like URIs, HTTP, URLs, HTML, web servers, and WYSIWYG editors that made content creation accessible to everyone.

Understanding REST

Breaking Down the Acronym

R - Representational

  • Resources are represented in different formats
  • Common formats: JSON, XML, HTML
  • The same resource can have multiple representations based on client needs

S - State

  • Refers to the current properties of a resource
  • State can be transferred between client and server
  • Server doesn't maintain client state between requests (stateless architecture)

T - Transfer

  • The movement of resource representations between client and server
  • Each request contains all information needed to understand it

Anatomy of a URL

https://google.com/blog/post?q=something#header
Enter fullscreen mode Exit fullscreen mode

Components:

  • Scheme: https or http - the protocol used
  • Domain/Authority: google.com - can include subdomains
  • Resources: /blog/post - hierarchical path showing resource relationships
  • Query Parameters: ?q=something - filters or search criteria
  • Fragment: #header - navigates to a specific section of the resource

Idempotency in HTTP Methods

Definition: An idempotent operation produces the same result no matter how many times it's executed.

Idempotent Methods

  • GET: Always returns the same resource (no side effects)
  • PUT: Updates a resource to the same state, multiple calls yield same result
  • DELETE: Deleting the same resource multiple times has the same effect
  • HEAD: Like GET but only returns headers
  • OPTIONS: Always returns the same allowed methods

Non-Idempotent Methods

  • POST: Creates new resources or performs actions, each call may produce different results

HTTP Methods and Their Uses

GET

  • Purpose: Retrieve resources
  • Idempotent: Yes
  • Safe: Yes (no side effects)
  • Use Cases:
    • Fetch a list of items
    • Retrieve a single item
    • Search and filter data
GET /api/articles
GET /api/articles/123
GET /api/articles?author=john&status=published
Enter fullscreen mode Exit fullscreen mode

POST

  • Purpose: Create resources or perform actions
  • Idempotent: No
  • Safe: No
  • Use Cases:
    • Create new resources
    • Perform custom actions
    • Send emails
    • Trigger workflows
    • Any action that doesn't fit CRUD
POST /api/articles
POST /api/articles/123/publish
POST /api/users/456/send-welcome-email
POST /api/orders/789/calculate-shipping
Enter fullscreen mode Exit fullscreen mode

Why POST is Open-Ended: When you need to perform an action that doesn't map to standard CRUD operations, POST is your go-to method. It's intentionally flexible for custom operations.

PUT

  • Purpose: Update entire resource or create if doesn't exist
  • Idempotent: Yes
  • Safe: No
  • Use Case: Replace complete resource
PUT /api/articles/123
Enter fullscreen mode Exit fullscreen mode

PATCH

  • Purpose: Partial update of resource
  • Idempotent: Usually yes
  • Safe: No
  • Use Case: Update specific fields
PATCH /api/articles/123
Enter fullscreen mode Exit fullscreen mode

DELETE

  • Purpose: Remove resources
  • Idempotent: Yes
  • Safe: No
  • Use Case: Delete resources
DELETE /api/articles/123
Enter fullscreen mode Exit fullscreen mode

REST API Design Principles

1. Resource Naming Conventions

Use Plural Nouns

✅ /api/articles
✅ /api/users
✅ /api/comments

❌ /api/article
❌ /api/user
❌ /api/comment
Enter fullscreen mode Exit fullscreen mode

Why Plural?

  • Consistency across endpoints
  • Collections naturally use plural
  • Easier to understand at a glance

Handle Whitespace in URLs

Input: "Harry Potter"
URL: /api/books/harry-potter

✅ Use hyphens (kebab-case)
❌ Avoid underscores or spaces
Enter fullscreen mode Exit fullscreen mode

2. Hierarchical Resource Relationships

GET /api/articles/123/comments
GET /api/articles/123/comments/456
POST /api/articles/123/comments
DELETE /api/users/789/preferences/notifications
Enter fullscreen mode Exit fullscreen mode

3. Query Parameters for Filtering

GET /api/articles?status=published&author=john&sort=date&order=desc
GET /api/users?role=admin&page=2&limit=20
Enter fullscreen mode Exit fullscreen mode

4. Versioning

/api/v1/articles
/api/v2/articles
Enter fullscreen mode Exit fullscreen mode

Or via headers:

Accept: application/vnd.api.v1+json
Enter fullscreen mode Exit fullscreen mode

The Critical 404 vs 200 Rule

When Fetching a Single Resource

GET /api/articles/999

Response: 404 Not Found
Enter fullscreen mode Exit fullscreen mode

Why? The specific resource doesn't exist - this is an error state.

When Fetching a Collection

GET /api/articles?author=unknown

Response: 200 OK
Body: []
Enter fullscreen mode Exit fullscreen mode

Why? The request was successful - an empty result set is valid data, not an error.

Designing REST APIs: The Process

Step 1: Design the Wireframe/UI First

Before writing a single line of API code, design the user interface or understand the client needs.

Questions to Ask:

  • What data does the user need to see?
  • What actions can they perform?
  • What filters or searches will they use?
  • How will they navigate between resources?

Example Flow:

[Homepage]
   ↓
[Article List] → Filter by category, author, date
   ↓
[Article Detail] → View comments
   ↓
[Comment Section] → Add/edit/delete comments
Enter fullscreen mode Exit fullscreen mode

Step 2: Map UI Components to API Endpoints

UI Component HTTP Method Endpoint Purpose
Article List GET /api/articles Fetch all articles
Article Filters GET /api/articles?category=tech Filtered list
Article Detail GET /api/articles/123 Single article
Create Article POST /api/articles New article
Edit Article PUT/PATCH /api/articles/123 Update article
Delete Article DELETE /api/articles/123 Remove article
Publish Article POST /api/articles/123/publish Custom action
Article Comments GET /api/articles/123/comments Nested resource
Add Comment POST /api/articles/123/comments Create comment

Step 3: Define Resource Structure

{
  "id": 123,
  "title": "Understanding REST APIs",
  "slug": "understanding-rest-apis",
  "author": {
    "id": 456,
    "name": "John Doe",
    "avatar": "https://..."
  },
  "content": "...",
  "status": "published",
  "category": "technology",
  "tags": ["api", "rest", "web-development"],
  "created_at": "2025-01-15T10:30:00Z",
  "updated_at": "2025-01-20T14:45:00Z",
  "comments_count": 42,
  "links": {
    "self": "/api/articles/123",
    "comments": "/api/articles/123/comments",
    "author": "/api/users/456"
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Plan Response Codes

Status Code Meaning Use Case
200 OK Success GET, PATCH successful
201 Created Resource created POST successful
204 No Content Success, no body DELETE successful
400 Bad Request Invalid input Validation errors
401 Unauthorized Not authenticated Missing/invalid token
403 Forbidden Not authorized Insufficient permissions
404 Not Found Resource missing Single resource not found
409 Conflict Resource conflict Duplicate resource
422 Unprocessable Validation failed Business logic errors
500 Server Error Server problem Unexpected errors

Step 5: Design Error Responses

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid input data",
    "details": [
      {
        "field": "email",
        "message": "Email is required"
      },
      {
        "field": "password",
        "message": "Password must be at least 8 characters"
      }
    ],
    "timestamp": "2025-01-20T14:45:00Z",
    "path": "/api/users"
  }
}
Enter fullscreen mode Exit fullscreen mode

Complete API Example

Blog Platform REST API

# Articles
GET    /api/v1/articles                    # List all articles
GET    /api/v1/articles?status=published   # Filter articles
GET    /api/v1/articles/understanding-rest # Get single article
POST   /api/v1/articles                    # Create article
PUT    /api/v1/articles/123                # Update full article
PATCH  /api/v1/articles/123                # Partial update
DELETE /api/v1/articles/123                # Delete article

# Custom Actions
POST   /api/v1/articles/123/publish        # Publish article
POST   /api/v1/articles/123/unpublish      # Unpublish article
POST   /api/v1/articles/123/duplicate      # Duplicate article

# Nested Resources
GET    /api/v1/articles/123/comments       # Get article comments
POST   /api/v1/articles/123/comments       # Add comment
GET    /api/v1/articles/123/comments/456   # Get single comment
PATCH  /api/v1/articles/123/comments/456   # Update comment
DELETE /api/v1/articles/123/comments/456   # Delete comment

# Authors
GET    /api/v1/authors                     # List authors
GET    /api/v1/authors/789                 # Get author profile
GET    /api/v1/authors/789/articles        # Author's articles

# Categories & Tags
GET    /api/v1/categories                  # List categories
GET    /api/v1/categories/tech/articles    # Articles in category
GET    /api/v1/tags                        # List tags
GET    /api/v1/tags/api/articles           # Articles with tag
Enter fullscreen mode Exit fullscreen mode

Best Practices Checklist

  • ✅ Use plural nouns for resources
  • ✅ Use hyphens in URLs (kebab-case)
  • ✅ Use nouns, not verbs in endpoints
  • ✅ Keep URLs lowercase
  • ✅ Version your API
  • ✅ Use proper HTTP methods
  • ✅ Return appropriate status codes
  • ✅ Use 404 for missing single resources
  • ✅ Use 200 with empty array for empty collections
  • ✅ Include links to related resources (HATEOAS)
  • ✅ Provide consistent error responses
  • ✅ Support filtering, sorting, and pagination
  • ✅ Document your API thoroughly
  • ✅ Use POST for custom actions
  • ✅ Design UI/UX before API

Conclusion

Great REST API design starts with understanding user needs through wireframes and UI flows. By following these principles—proper resource naming, appropriate HTTP methods, clear response codes, and the critical distinction between empty results and missing resources—you create APIs that are intuitive, maintainable, and developer-friendly.

Remember: Design for your users first, then build the API that serves their needs. The technical excellence of your REST API should be invisible to end users, manifesting only as a seamless, fast, and reliable experience.


Happy API building! 🚀

Top comments (0)