Bird
Raised Fist0

REST API Design Principles - Resources, Methods, Status Codes, Pagination

HLDmediumInterview freq: common
Choose your preparation mode4 modes available
🏗️
REST API Design Principles - Resources, Methods, Status Codes, Pagination
Designing scalable, consistent, and user-friendly REST APIs with best practices on resources, HTTP methods, status codes, and pagination.
mediumAPI Design and GatewayFreq: common
Prerequisites:System Design FundamentalsCAP TheoremHTTP Protocol BasicsREST Architectural Style
⚙️
Functional Requirements
  • Design RESTful resource URIs that are intuitive and hierarchical
  • Use appropriate HTTP methods (GET, POST, PUT, PATCH, DELETE) per resource action
  • Return standardized HTTP status codes for success and error scenarios
  • Implement pagination for list endpoints to handle large datasets
  • Support filtering and sorting on list endpoints
  • Ensure APIs are versioned for backward compatibility
📊
Non-Functional Requirements
  • Support up to 2 billion daily active users (DAU)
  • Ensure 99.99% API availability SLA
  • Maintain 100ms P99 latency for read endpoints
  • Handle peak write QPS of approximately 925K requests/sec
  • Support horizontal scalability and fault tolerance
❓
Clarifying Questions to Ask
  • What are the primary resources and their relationships in the system?
  • What is the expected read-to-write ratio for the APIs?
  • Are there any constraints on payload size or response formats?
  • Should the API support partial updates or only full resource replacement?
  • What pagination style is preferred: offset-based, cursor-based, or keyset?
  • How should error responses be structured for client debugging?
Out of Scope
✗ Authentication and authorization mechanisms
✗ API gateway implementation details
✗ Backend business logic and database schema design beyond API contract
✗ Client SDK generation
📌
Assumptions
  • 2 billion DAU generating 40 API calls per user per day
  • Average request/response payload size is 100 bytes
  • Retention period for logs and metrics is 30 days
  • Replication factor for storage is 3 for durability
⚡
QPS Calculation
write qps2B × 40 / 86400 ≈ 925,926 writes/sec
peak write qpsAssuming 3× peak factor → 2,777,778 writes/sec
read qpsAssuming 5× read-to-write ratio → 4,629,630 reads/sec
💾
Storage Estimate
daily storage2,925,926 writes × 100 bytes = 92.6 GB/day
retention storage92.6 GB × 30 days = 2.78 TB
with replication2.78 TB × 3 = 8.34 TB total storage
🖥️
Server Estimate
api serversAssuming 100ms P99 latency and 100 req/sec per server → 46,296 servers
database nodesUsing Cassandra with 100K writes/sec per node → 28 nodes for writes
🏗️
Architecture Diagram
Architecture Diagram
          +-------------+
          |   Clients   |
          +------+------+
                 |
                 v
          +------+-------+
          |  API Gateway |
          +------+-------+
                 |
        +--------+---------+
        |                  |
  +-----v-----+      +-----v-----+
  | Auth Svc |      | Rate Limiter|
  +-----+-----+      +-----+-----+
        |                  |
        +--------+---------+
                 |
          +------+-------+
          | REST API Svc |
          +------+-------+
                 |
          +------+-------+
          |  Cassandra   |
          +--------------+
🧩
Components
API Gateway
Entry point for all client requests, routing to appropriate services
Why thisEnvoy proxy supports dynamic routing, rate limiting, and TLS termination at scale
Why notNginx lacks native dynamic service discovery and advanced routing features needed at 2B DAU
Rate Limiter
Protect backend services from overload by enforcing request quotas
Why thisRedis with Lua scripts provides atomic counters and sub-millisecond latency for rate limiting
Why notMemcached lacks atomic increment operations, risking race conditions under high concurrency
REST API Service
Implements REST endpoints with resource modeling, methods, status codes, and pagination
Why thisSpring Boot framework supports RESTful design, validation, and integrates with OpenAPI for docs
Why notExpress.js single-threaded model struggles with 925K writes/sec peak load
Cassandra
Distributed NoSQL database storing resource data with high write throughput and availability
Why thisCassandra's tunable consistency and linear write scalability handle 2.7M writes/sec with replication
Why notPostgreSQL requires complex manual sharding and cannot sustain 925K writes/sec without bottlenecks
Auth Service
Validates client tokens and permissions for API access
Why thisOAuth 2.0 server with JWT tokens enables stateless, scalable authentication
Why notSession-based auth requires sticky sessions and stateful storage, limiting horizontal scaling
🔄
Data Flow
1
Client → API Gateway
Client sends REST API request with resource URI and HTTP method
Gateway handles TLS termination and initial routing
2
API Gateway → Rate Limiter
Check client request quota and throttle if exceeded
Prevents backend overload during traffic spikes
3
API Gateway → Auth Service
Validate client authentication token
Ensures only authorized requests proceed
4
API Gateway → REST API Service
Forward validated request to REST API service
Service parses resource, method, and parameters
5
REST API Service → Cassandra
Perform read/write operation based on HTTP method
Uses appropriate query patterns for pagination and filtering
6
Cassandra → REST API Service
Return data or write confirmation
Service formats response with correct status codes
7
REST API Service → API Gateway
Send HTTP response with status code and payload
Gateway forwards response to client

Practice

(1/5)
1. In a sliding window rate limiter, at step 3 the system records a new request timestamp. What happens internally to the stored counters at this step?
easy
A. Old timestamps outside the sliding window are removed before adding the new timestamp
B. The leaky bucket drains tokens at a fixed rate before accepting the request
C. The token bucket refills tokens based on elapsed time before decrementing
D. The fixed window counter resets to zero if the current minute changed

Solution

  1. Step 1: Understand sliding window counter mechanics

    Sliding window counters maintain timestamps of recent requests and remove those outside the window to keep an accurate count.
  2. Step 2: At step 3, old timestamps beyond the window are purged before adding the new request timestamp

    This ensures the count reflects only requests within the sliding window duration.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Sliding window removes expired timestamps before counting new requests [check]
Hint: Sliding window purges old timestamps before counting new ones [check]
Common Mistakes:
2. A web application requires multiplexing multiple requests over a single TCP connection to reduce latency. Which HTTP version feature primarily enables this?
easy
A. HTTP/3 using UDP datagrams without multiplexing
B. HTTP/1.1 pipelining with multiple TCP connections
C. HTTP/2 multiplexing streams over one TCP connection
D. HTTP/1.1 using separate TCP connections per request

Solution

  1. Step 1: Identify multiplexing capability

    HTTP/1.1 uses pipelining but suffers head-of-line blocking; HTTP/2 introduces multiplexing streams over a single TCP connection, allowing concurrent requests without blocking.
  2. Step 2: Eliminate other options

    HTTP/3 uses UDP and multiplexing but is not the primary feature here; HTTP/1.1 with multiple TCP connections increases overhead and latency.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    HTTP/2 multiplexes streams on one TCP connection [check]
Hint: HTTP/2 multiplexes streams on one TCP connection [check]
Common Mistakes:
3. At 10x scale, which component is most likely to fail first and why?
hard
A. The delivery workers, due to Kafka consumer lag and processing bottlenecks
B. The chat servers maintaining WebSocket connections, due to stateful connection limits
C. The relational database storing tweets, due to write amplification from fan-out
D. The timeline cache servers, due to memory pressure from large follower counts

Solution

  1. Step 1: Analyze timeline cache scaling challenges

    Timeline caches hold per-user timelines; large follower counts cause exponential memory growth.
  2. Step 2: Compare other components

    Relational DB (A) is mostly append-only and sharded; chat servers (B) irrelevant here; delivery workers (D) scale with Kafka partitions.
  3. Step 3: Identify first failure point

    Memory pressure on timeline caches causes eviction and stale timelines first at 10x scale.
  4. Final Answer:

    Option D -> Option D
  5. Quick Check:

    Timeline caches hit memory limits first due to follower fan-out [check]
Hint: Timeline caches hit memory bottleneck first at scale [check]
Common Mistakes:
4. At 10x traffic scale, which component in a GeoDNS-based global traffic distribution system is most likely to fail first and why?
hard
A. Authoritative DNS servers, because they maintain stateful session info for each client
B. GeoDNS servers, because DNS query rate increases and caching TTLs limit cache effectiveness
C. Data center load balancers, because they cannot handle increased TCP connection counts
D. Network routers, because they cannot route Anycast IPs at scale

Solution

  1. Step 1: Identify GeoDNS scaling bottleneck

    GeoDNS servers handle DNS queries globally; at 10x scale, query volume spikes, and short TTLs reduce cache hits, increasing load.
  2. Step 2: Eliminate other options

    Authoritative DNS servers (A) are stateless per query. Data center load balancers (C) scale horizontally and are not the first bottleneck. Network routers (D) handle Anycast well at scale.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    GeoDNS query load spikes with limited caching cause first failure [check]
Hint: GeoDNS query load spikes first due to limited caching [check]
Common Mistakes:
5. At 10x scale, which component in a message queue system is most likely to fail first and why?
hard
A. The database storing consumer offsets, because it cannot handle the increased write volume
B. The message broker's partition leader nodes, due to increased network I/O and disk throughput limits
C. The chat servers maintaining WebSocket connections, because stateful connections cannot be resharded easily
D. The producers, because they cannot generate messages fast enough to keep up with demand

Solution

  1. Step 1: Analyze stateful components at scale

    Chat servers maintain stateful WebSocket connections bound to server memory; scaling requires connection migration which is complex.
  2. Step 2: Compare other components

    Database (A) and brokers (B) can be scaled horizontally with sharding and replication; producers (D) can be scaled out by adding more instances.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Stateful WebSocket servers bottleneck scaling due to connection affinity [check]
Hint: Stateful WebSocket servers bottleneck scaling first [check]
Common Mistakes:
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard