GoodNotes Architect Journal
🏠 Index 1. Single Server 2. Selecting DB 3. Relational & SQL 4. ACID Integrity 5. NoSQL Types 6. Scaling Guide 7. Load Balancing 8. SPOF & HA 9. API Design 10. Comm Protocols 11. TCP & UDP 12. REST Design 13. GraphQL Architecture 14. Authentication Protocols 15. JWT & OAuth 2 16. Authorization Models
System Design Chapter 12

RESTful API Design & Resource Modeling

Domain-to-Resource Mapping, Query Modifiers, HTTP Methods Safety/Idempotency, Status Codes, & Best Practices

★ Masterclass in RESTful architecture: clean URIs, expressive query params & strict status codes!

1 Resource Modeling: From Business Domain to REST Endpoints

In RESTful (Representational State Transfer) architecture, real-world business entities are abstracted into pluralized, noun-based Resources identified by clean, intuitive, and predictable URIs.

🏗️ Business Domain ➔ REST Resource Mapping Architecture

🏢 1. Business Domain Entities (Data Layer)

📦 Product
Fields: id, title, price, stock
🛒 Order
Fields: id, user_id, total, status
⭐ Review
Fields: id, product_id, rating
⬇️

Mapped to Pluralized REST Resource Collections

⬇️

🌐 2. REST API Resource Collections (Interface Layer)

/api/v1/products
Collection endpoint for products
/api/v1/orders
Collection endpoint for orders
/api/v1/reviews
Collection endpoint for reviews

🏛️ 1. Nouns Over Verbs

URIs represent things (resources), not actions. Use /orders instead of /createOrder or /getOrders. The HTTP method specifies the action.

🏷️ 2. Pluralized Standard

Collections use plural nouns (/products). A specific entity is addressed via its unique identifier in the path (/products/{id}).

2 Hierarchical URL Patterns & Identifier Routing

Endpoints should follow a strict hierarchical structure with API versioning prefixes, plural noun resource paths, and unique resource identifiers:

📐 Clean REST URI Structure Anatomy
Protocol + Hosthttps://api.domain.com
/
Version Prefixapi/v1
/
Resource Collectionproducts
/
Entity ID{id}
/
Sub-Resourcereviews

📦 Products Resource Endpoints

GET/api/v1/products
➔ Retrieve list of product collection
GET/api/v1/products/{id}
➔ Fetch single product by UUID / ID (e.g., /products/4d3e…)

🛒 Orders Resource Endpoints

GET/api/v1/orders
➔ List authenticated user’s order history
POST/api/v1/orders
➔ Submit and create new checkout order
⭐ Sub-Resource / Nested Endpoint Modeling

When an entity is naturally owned by or subordinate to another parent entity, express the relation hierarchically in the path:

GET/api/v1/products/{productId}/reviews

📌 Design Rule of Thumb: Limit nesting to a maximum of 2 levels deep (e.g., /products/{id}/reviews). Deeply nested paths like /users/1/orders/2/items/3/taxes indicate poor modeling; flatten them to top-level collections with query filters (/order-items?order_id=2).

3 Query Parameters: Filtering, Sorting & Pagination

Rather than creating dedicated endpoint paths for every query permutation, use standardized Query Parameters (?key=value) to modify, constrain, and structure collection responses.

🔍 1. Attribute Filtering (?key=value)
GET/api/v1/products?category=books&inStock=true
⚡ Backend Action: Appends WHERE category = ‘books’ AND in_stock = true to SQL query.
HTTP 200 OK — Filtered Products Payload
[
{
“id”: 101,
“title”: “Designing APIs with Swagger”,
“category”: “books”,
“inStock”: true,
“price”: 29.99
}
]
📶 2. Collection Sorting (?sort=field)
GET/api/v1/products?sort=price:asc
⚡ Backend Action: Appends ORDER BY price ASC (use -price or price:desc for descending).
HTTP 200 OK — Sorted Products Payload
[
{
“id”: 201,
“title”: “Wireframe UI Kit”,
“price”: 9.99
},
{
“id”: 202,
“title”: “Figma Pro Component Library”,
“price”: 19.00
}
]
📄 3. Pagination & Envelope Metadata (?page=2&limit=3)
GET/api/v1/products?page=2&limit=3
⚡ Backend Action: Appends LIMIT 3 OFFSET 3 with envelope pagination metadata.
HTTP 200 OK — Paginated Envelope Response
{
“page”: 2,
“limit”: 3,
“total_records”: 124,
“total_pages”: 42,
“has_more”: true,
“data”: [
{
“id”: 301,
“title”: “Next.js Architecture Handbook”,
“price”: 15.00
}
]
}

🚀 3 Core Benefits of Standardized Query Modifiers

  • Saves Network Bandwidth: Prevents massive multi-megabyte payloads by only sending requested subsets over the wire.
  • Protects Database & Server: Leverages B-Tree index scans, bounds SQL execution times with LIMIT, and prevents Out-of-Memory (OOM) crashes.
  • Unlocks Rich Frontend UX: Supports responsive pagination controls, dynamic sorting chips, and instant search-as-you-type filters.

4 HTTP Methods: CRUD, Safety & Idempotency Rules

Every HTTP request verb communicates precise operational semantics regarding resource mutation, safety guarantees, and idempotency repeatability under network retries.

MethodCRUD ActionEndpoint ExampleSafe?Idempotent?
GETRead / RetrieveGET /api/v1/products/123✅ Safe✅ Idempotent
POSTCreate / ActionPOST /api/v1/products❌ Unsafe❌ Non-Idempotent
PUTUpdate (Full Replace)PUT /api/v1/products/123❌ Unsafe✅ Idempotent
PATCHUpdate (Partial)PATCH /api/v1/products/123❌ Unsafe❌ Non-Idempotent*
DELETEDelete / DestroyDELETE /api/v1/products/123❌ Unsafe✅ Idempotent
🔒 Definition: Safe Methods

Safe Methods are strictly read-only and guarantee zero server-side state mutation. Clients can pre-fetch, cache, and execute them unconditionally (e.g., GET, HEAD, OPTIONS).

🔁 Definition: Idempotent Methods

Idempotent Methods produce the exact same server state whether executed 1 time or repeated 1,000 times ($f(f(x)) = f(x)$). Crucial for safe automatic network retries during network timeouts (e.g., PUT, DELETE, GET).

5 HTTP Status Codes & Standardized Error Handling

Well-engineered REST APIs communicate operational outcomes using standardized 3-digit HTTP status codes. Avoid returning 200 OK with an embedded error payload.

🟢 2xx: Success

200 OKStandard successful response (GET, PUT, PATCH).
201 CreatedNew resource created (returns Location header).
204 No ContentAction succeeded; no body returned (e.g., DELETE).

🟡 3xx: Redirection

301 Moved PermanentlyTarget resource permanently assigned new URI.
304 Not ModifiedConditional GET: cached client copy is still valid.

🟠 4xx: Client Errors

400 Bad RequestMalformed JSON payload or invalid query syntax.
401 UnauthorizedMissing, invalid, or expired authentication token.
403 ForbiddenAuthenticated client lacks sufficient RBAC permissions.
404 Not FoundRequested resource URI does not exist.
429 Too Many RequestsRate limit exceeded (returns Retry-After header).

🔴 5xx: Server Errors

500 Internal ErrorUnhandled backend exception or database failure.
502 Bad GatewayReverse proxy / Load Balancer received invalid upstream response.
503 UnavailableServer temporarily overloaded or undergoing scheduled maintenance.
504 Gateway TimeoutUpstream microservice timed out during proxy processing.
📋 RFC 7807: Standardized Problem Details Error Payload
{
“type”: “https://api.example.com/errors/insufficient-inventory”,
“title”: “Insufficient Inventory”,
“status”: 422,
“detail”: “Product 101 only has 2 items in stock, but 5 were requested.”,
“instance”: “/orders/checkout/req_9874”,
“invalid_params”: [
{
“name”: “quantity”,
“reason”: “Quantity requested exceeds available stock”
}
]
}

6 API Design Best Practices: Anti-Patterns vs. REST Standards

📋 4 Golden Principles of RESTful API Architecture:
  1. Use Plural Nouns for Resources: Never embed verbs in URIs (use /users, /orders).
  2. Model Hierarchical Parentage Intuitively: Reflect ownership via clean paths (/products/123/reviews).
  3. Expose Expressive Query Modifiers: Provide filtering, sorting, and pagination on all collection routes.
  4. Explicit API Versioning: Always prefix paths with version identifiers (/api/v1/…) to ensure backward compatibility.

⚖️ Direct Comparison: Anti-Patterns vs. RESTful Standards

❌ Poor API Design (Anti-Pattern)✅ Good API Design (RESTful Standard)
GET /getUser/123
⚠️ Anti-Pattern: Action verb embedded in URI path + singular noun.
GET /api/v1/users/123
✅ REST: Standard HTTP GET verb targeting plural collection with version.
POST /users/123/delete
⚠️ Anti-Pattern: RPC-style method disguised inside a POST request.
DELETE /api/v1/users/123
✅ REST: Idempotent HTTP DELETE method on target resource identifier.
GET /products (returning 50,000 items)
⚠️ Anti-Pattern: Unbounded full-table database dumps risking server OOM.
GET /api/v1/products?page=1&limit=25&sort=price:asc
✅ REST: Bounded pagination envelope with explicit limits and sorting.
HTTP 200 OK { “error”: “Not found” }
⚠️ Anti-Pattern: Masking failures under 200 OK breaks CDN caching and clients.
HTTP 404 Not Found { “title”: “User not found” }
✅ REST: Standardized status codes conforming to RFC 7807 problem details.
“
REST is not a protocol or a strict standard—it is an architectural style that leverages existing HTTP capabilities to build scalable, decoupled, and self-descriptive distributed systems.
— Roy Fielding — Architectural Styles and the Design of Network-based Software Architectures