Nextgen Blog
HomeLearnAIQuantumRoboticsSecuritySpaceAbout
Nextgen Blog

By Anubhav — full stack engineer, IIT Mandi CSE. Deep dives into AI, software engineering, and the technologies shaping the next generation of tech.

Navigate

  • Home
  • Learn
  • Blog
  • Archive
  • About

Topics

  • Artificial Intelligence
  • Quantum Computing
  • Robotics
  • Cybersecurity
  • Space Tech

Connect

Built with ❤️ & By - Anubhav

© 2026 Nextgen Blog by Anubhav. All rights reserved.

Privacy PolicyTerms of Service
Phase 01 · Foundations & Web ArchitectureChapter 6 of 33
05.
Phase 01Read time ~33 minDifficulty advanced

HTTP & API Design

In this chapter
  • 01Chapter Overview
  • 02What Is HTTP?
  • 03HTTP and the Network Stack
  • 04HTTP Versions
  • 05HTTP/1.1
  • 06HTTP/2
  • 07HTTP/3
  • 08HTTP Request
  • 09Request Line
  • 10Request Headers
  • 11Request Body
  • 12HTTP Response
  • 13HTTP Methods
  • 14GET
  • 15POST
  • 16PUT
  • 17PATCH
  • 18DELETE
  • 19Safe vs Idempotent Methods
  • 20Safe
  • 21Idempotent
  • 22HTTP Status Codes
  • 23Important 2xx Codes
  • 24OK
  • 25Created
  • 26Accepted
  • 27No Content
  • 28Important 3xx Codes
  • 29Moved Permanently
  • 30Found
  • 31Not Modified
  • 32Important 4xx Codes
  • 33Bad Request
  • 34Unauthorized
  • 35Forbidden
  • 36Not Found
  • 37Method Not Allowed
  • 38Conflict
  • 39Too Many Requests
  • 40Important 5xx Codes
  • 41Internal Server Error
  • 42Bad Gateway
  • 43Service Unavailable
  • 44Gateway Timeout
  • 45vs 403
  • 46HTTP Headers
  • 47Content-Type
  • 48Accept
  • 49Authorization Header
  • 50Cookies
  • 51Cookie-Based Authentication
  • 52Important Cookie Security Attributes
  • 53HttpOnly
  • 54Secure
  • 55SameSite
  • 56Sessions
  • 57Stateful Session Problem
  • 58Sticky Sessions
  • 59Stateless APIs
  • 60REST API
  • 61Resource-Oriented API Design
  • 62Nested Resources
  • 63JSON
  • 64API Response Design
  • 65Authentication vs Authorization
  • 66Authentication
  • 67Authorization
  • 68API Keys
  • 69JWT
  • 70JWT Request Flow
  • 71OAuth
  • 72Idempotency
  • 73Idempotency Keys
  • 74Idempotency-Key Storage
  • 75Pagination
  • 76Offset Pagination
  • 77Cursor Pagination
  • 78Pagination Response
  • 79Filtering
  • 80Sorting
  • 81Searching
  • 82Rate Limiting
  • 83Why Rate Limiting Matters in System Design
  • 84Common Rate-Limiting Algorithms
  • 85Fixed Window
  • 86Sliding Window
  • 87Token Bucket
  • 88Leaky Bucket
  • 89Where Should Rate Limiting Happen?
  • 90API Versioning
  • 91URL Versioning
  • 92Header-Based Versioning
  • 93Backward Compatibility
  • 94API Gateway
  • 95Reverse Proxy vs API Gateway
  • 96Request Timeout
  • 97Retries
  • 98Exponential Backoff
  • 99HTTP Caching
  • 100ETag
  • 101Conditional Requests
  • 102Compression
  • 103Request Correlation IDs
  • 104API Error Design
  • 105API Security Basics
  • 106Authentication
  • 107Authorization
  • 108Input validation
  • 109Rate limiting
  • 110TLS
  • 111Secret management
  • 112Logging
  • 113Least privilege
  • 114Input Validation
  • 115API Payload Size Limits
  • 116API Design Example — User Service
  • 117Create user
  • 118Get user
  • 119Update user
  • 120Delete user
  • 121List users
  • 122API Design Example — Orders
  • 123Synchronous vs Asynchronous APIs
  • 124Webhooks
  • 125API Design and Database Design
  • 126API Contract
  • 127API Gateway + Rate Limiter + Services
  • 128API Latency Budget
  • 129P50, P95, P99
  • 130Common HTTP/API Mistakes
  • 131Mistake 1 — Treating HTTP as the entire network
  • 132Mistake 2 — Confusing 401 and 403
  • 133Mistake 3 — Assuming POST retries are safe
  • 134Mistake 4 — Returning huge datasets
  • 135Mistake 5 — No timeout
  • 136Mistake 6 — Blind retries
  • 137Mistake 7 — Storing session state only in local memory
  • 138Mistake 8 — Putting sensitive information in JWT payloads
  • 139Mistake 9 — Exposing internal errors
  • 140Mistake 10 — Designing API URLs around database tables
  • 141Beginner Mental Model vs Technical Reality
  • 142Beginner mental model
  • 143More realistic system
  • 144Interview Questions
  • 145Q1. What happens when a browser sends an HTTP request?
  • 146Q2. GET vs POST?
  • 147Q3. PUT vs PATCH?
  • 148Q4. 401 vs 403?
  • 149Q5. Why use pagination?
  • 150Q6. Offset vs cursor pagination?
  • 151Q7. Why is idempotency important in payment APIs?
  • 152Q8. Why use an API gateway?
  • 153Q9. Why are timeouts important?
  • 154Q10. Why can retries be dangerous?
  • 155Practical Exercise
  • 156Mini Project — Production-Style Task API
  • 157Chapter Summary
  • 158HTTP
  • 159Status Codes
  • 160State and Authentication
  • 161API Design
  • 162Production Concerns
  • 163The Big Picture
  • 164Chapter 04 Master Checklist
  • 165What Comes Next?
  • 166Chapter 05 — Servers & Application Architecture
In this chapter (166 sections)
01Chapter Overview02What Is HTTP?03HTTP and the Network Stack04HTTP Versions05HTTP/1.106HTTP/207HTTP/308HTTP Request09Request Line10Request Headers11Request Body12HTTP Response13HTTP Methods14GET15POST16PUT17PATCH18DELETE19Safe vs Idempotent Methods20Safe21Idempotent22HTTP Status Codes23Important 2xx Codes24OK25Created26Accepted27No Content28Important 3xx Codes29Moved Permanently30Found31Not Modified32Important 4xx Codes33Bad Request34Unauthorized35Forbidden36Not Found37Method Not Allowed38Conflict39Too Many Requests40Important 5xx Codes41Internal Server Error42Bad Gateway43Service Unavailable44Gateway Timeout45vs 40346HTTP Headers47Content-Type48Accept49Authorization Header50Cookies51Cookie-Based Authentication52Important Cookie Security Attributes53HttpOnly54Secure55SameSite56Sessions57Stateful Session Problem58Sticky Sessions59Stateless APIs60REST API61Resource-Oriented API Design62Nested Resources63JSON64API Response Design65Authentication vs Authorization66Authentication67Authorization68API Keys69JWT70JWT Request Flow71OAuth72Idempotency73Idempotency Keys74Idempotency-Key Storage75Pagination76Offset Pagination77Cursor Pagination78Pagination Response79Filtering80Sorting81Searching82Rate Limiting83Why Rate Limiting Matters in System Design84Common Rate-Limiting Algorithms85Fixed Window86Sliding Window87Token Bucket88Leaky Bucket89Where Should Rate Limiting Happen?90API Versioning91URL Versioning92Header-Based Versioning93Backward Compatibility94API Gateway95Reverse Proxy vs API Gateway96Request Timeout97Retries98Exponential Backoff99HTTP Caching100ETag101Conditional Requests102Compression103Request Correlation IDs104API Error Design105API Security Basics106Authentication107Authorization108Input validation109Rate limiting110TLS111Secret management112Logging113Least privilege114Input Validation115API Payload Size Limits116API Design Example — User Service117Create user118Get user119Update user120Delete user121List users122API Design Example — Orders123Synchronous vs Asynchronous APIs124Webhooks125API Design and Database Design126API Contract127API Gateway + Rate Limiter + Services128API Latency Budget129P50, P95, P99130Common HTTP/API Mistakes131Mistake 1 — Treating HTTP as the entire network132Mistake 2 — Confusing 401 and 403133Mistake 3 — Assuming POST retries are safe134Mistake 4 — Returning huge datasets135Mistake 5 — No timeout136Mistake 6 — Blind retries137Mistake 7 — Storing session state only in local memory138Mistake 8 — Putting sensitive information in JWT payloads139Mistake 9 — Exposing internal errors140Mistake 10 — Designing API URLs around database tables141Beginner Mental Model vs Technical Reality142Beginner mental model143More realistic system144Interview Questions145Q1. What happens when a browser sends an HTTP request?146Q2. GET vs POST?147Q3. PUT vs PATCH?148Q4. 401 vs 403?149Q5. Why use pagination?150Q6. Offset vs cursor pagination?151Q7. Why is idempotency important in payment APIs?152Q8. Why use an API gateway?153Q9. Why are timeouts important?154Q10. Why can retries be dangerous?155Practical Exercise156Mini Project — Production-Style Task API157Chapter Summary158HTTP159Status Codes160State and Authentication161API Design162Production Concerns163The Big Picture164Chapter 04 Master Checklist165What Comes Next?166Chapter 05 — Servers & Application Architecture

1. Chapter Overview#

In the previous chapters, we learned:

  • how a web application works
  • how clients communicate over networks
  • TCP, UDP, QUIC, TLS, and ports
  • how DNS finds the destination server
  • how DNS caching, routing, CDN integration, and service discovery work

Now we reach the next important layer:

How does the client actually communicate with the application?

That communication is commonly handled through HTTP.

A simplified request path is:

User
  ↓
Browser / Mobile App
  ↓
DNS
  ↓
IP Address
  ↓
TCP / QUIC
  ↓
TLS
  ↓
HTTP Request
  ↓
Load Balancer / Reverse Proxy
  ↓
Application
  ↓
Cache / Database / Other Services
  ↓
HTTP Response
  ↓
Client

HTTP is therefore one of the most important foundations of system design.

This chapter covers:

  1. HTTP fundamentals
  2. HTTP requests
  3. HTTP responses
  4. HTTP methods
  5. HTTP headers
  6. HTTP status codes
  7. Cookies
  8. Sessions
  9. REST APIs
  10. JSON
  11. Authentication
  12. Authorization
  13. Idempotency
  14. Pagination
  15. Rate limiting
  16. API versioning
  17. API design best practices
  18. Production API concerns
  19. Common mistakes
  20. Interview questions
  21. Exercises
  22. Mini project

2. What Is HTTP?#

HTTP stands for:

Hypertext Transfer Protocol

It is an application-layer protocol used for communication between clients and servers.

The client sends a request.

The server sends a response.

Client ─────── HTTP Request ───────→ Server
 
Client ←────── HTTP Response ─────── Server

For example:

GET /users/123 HTTP/1.1
Host: example.com
Accept: application/json

The server may respond:

HTTP/1.1 200 OK
Content-Type: application/json
 
{
  "id": 123,
  "name": "Anubhav"
}

HTTP itself does not normally store application state.

It primarily defines how messages are structured and exchanged.


3. HTTP and the Network Stack#

It is important to understand where HTTP sits.

A simplified stack is:

Application
    │
    │ HTTP
    ↓
Transport
    │
    │ TCP / QUIC
    ↓
Internet
    │
    │ IP
    ↓
Network / Link

With HTTPS:

HTTP
 ↓
TLS
 ↓
TCP
 ↓
IP

For HTTP/3:

HTTP/3
 ↓
QUIC
 ↓
UDP
 ↓
IP

The exact protocol stack depends on the HTTP version.


4. HTTP Versions#

The major versions you should know for system design are:

Version Important idea
HTTP/1.0 Basic request/response
HTTP/1.1 Persistent connections, chunked transfer, Host header
HTTP/2 Binary framing, multiplexing, header compression
HTTP/3 HTTP over QUIC

HTTP/1.1#

HTTP/1.1 commonly uses persistent TCP connections.

Example:

TCP Connection
    ├── Request 1
    ├── Response 1
    ├── Request 2
    ├── Response 2
    └── Request 3

HTTP/2#

HTTP/2 introduces multiplexing.

Multiple streams can share one connection.

One TCP Connection
 
 ├── Stream 1 → Request A
 ├── Stream 2 → Request B
 ├── Stream 3 → Request C
 └── Stream 4 → Request D

This reduces some of the connection-management overhead found in HTTP/1.x.

HTTP/3#

HTTP/3 uses QUIC instead of TCP.

HTTP/3
   ↓
 QUIC
   ↓
 UDP

One important advantage is that QUIC provides independent streams, helping avoid some forms of TCP-level head-of-line blocking.

For system design interviews, remember:

HTTP/1.1 → persistent connections
HTTP/2   → multiplexing
HTTP/3   → QUIC

5. HTTP Request#

An HTTP request generally contains:

Request Line
Headers
Blank Line
Optional Body

Example:

POST /api/users HTTP/1.1
Host: example.com
Content-Type: application/json
Authorization: Bearer <token>
 
{
  "name": "Anubhav",
  "email": "user@example.com"
}

Let's break this down.


6. Request Line#

The request line contains:

METHOD PATH VERSION

Example:

GET /api/users/123 HTTP/1.1

Here:

  • GET = HTTP method
  • /api/users/123 = request target
  • HTTP/1.1 = HTTP version

7. Request Headers#

Headers provide metadata about the request.

Example:

Host: example.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer token
User-Agent: Mozilla/5.0

Headers can communicate:

  • content type
  • accepted response formats
  • authentication information
  • caching instructions
  • client information
  • tracing information
  • compression support

8. Request Body#

The body carries data sent by the client.

Example:

{
  "name": "Anubhav",
  "email": "user@example.com"
}

A request body is common with:

  • POST
  • PUT
  • PATCH

It is generally not needed for a normal GET request.


9. HTTP Response#

The server response contains:

Status Line
Headers
Blank Line
Optional Body

Example:

HTTP/1.1 200 OK
Content-Type: application/json
 
{
  "id": 123,
  "name": "Anubhav"
}

The status line contains:

HTTP VERSION
STATUS CODE
REASON PHRASE

For example:

HTTP/1.1 200 OK

10. HTTP Methods#

HTTP methods describe the intended operation.

The most important methods are:

Method Typical purpose
GET Read data
POST Create resource / trigger operation
PUT Replace resource
PATCH Partially update resource
DELETE Delete resource
HEAD Get headers without response body
OPTIONS Discover supported communication options

11. GET#

GET retrieves information.

Example:

GET /users/123

Response:

{
  "id": 123,
  "name": "Anubhav"
}

GET should generally be safe and should not intentionally modify server state.


12. POST#

POST commonly creates a resource or triggers an operation.

Example:

POST /users

Body:

{
  "name": "Anubhav",
  "email": "user@example.com"
}

Possible response:

HTTP/1.1 201 Created

POST is not inherently idempotent.

If a client repeats:

POST /payments

the server might create multiple payments unless the API has an idempotency mechanism.

This becomes extremely important in payment systems.


13. PUT#

PUT is generally used to replace the representation of a resource.

Example:

PUT /users/123

Body:

{
  "name": "Anubhav",
  "email": "new@example.com"
}

Conceptually:

Existing User
      ↓
Replace with supplied representation

PUT is generally considered idempotent when designed according to its semantics.


14. PATCH#

PATCH is commonly used for partial modification.

Example:

PATCH /users/123

Body:

{
  "name": "Warrior"
}

Only the specified field is changed.

Conceptually:

User
 ├── id       → unchanged
 ├── name     → changed
 └── email    → unchanged

15. DELETE#

DELETE requests removal of a resource.

Example:

DELETE /users/123

Possible response:

204 No Content

Whether repeated DELETE calls produce exactly the same server state depends on implementation, but DELETE is generally treated as idempotent by HTTP semantics.


16. Safe vs Idempotent Methods#

These terms are frequently asked in interviews.

Safe#

A safe method is intended not to change server state.

Examples:

GET
HEAD
OPTIONS

Idempotent#

A method is idempotent if making the same request multiple times has the same intended effect on server state as making it once.

Examples generally include:

GET
PUT
DELETE
HEAD
OPTIONS

POST is generally not idempotent.

Important:

Idempotent does not mean the response must be identical.

For example, the first DELETE may return:

204 No Content

and a later DELETE may return:

404 Not Found

The key concept is the intended state effect.


17. HTTP Status Codes#

Status codes tell the client what happened.

They are grouped into five classes:

1xx → Informational
2xx → Success
3xx → Redirection
4xx → Client-side error
5xx → Server-side error

18. Important 2xx Codes#

200 OK#

General successful request.

200 OK

Common with GET.


201 Created#

A resource was successfully created.

201 Created

Common with POST.


202 Accepted#

The request was accepted for processing, but processing is not necessarily complete.

Very useful for asynchronous systems.

Example:

POST /video-processing
       ↓
202 Accepted
       ↓
Background worker processes video

204 No Content#

Successful request with no response body.

Common for:

DELETE

or certain update operations.


19. Important 3xx Codes#

301 Moved Permanently#

The resource has permanently moved.

302 Found#

Temporary redirection behavior.

304 Not Modified#

Useful with HTTP caching.

Example:

Client
  ↓
GET /image.jpg
  If-None-Match: "abc"
  ↓
Server
  ↓
304 Not Modified

The client can use its cached copy.


20. Important 4xx Codes#

400 Bad Request#

The request is malformed or invalid.

Example:

{
  "email": "not-an-email"
}

401 Unauthorized#

The client has not provided valid authentication credentials.

A common practical interpretation:

Authentication is required or failed.


403 Forbidden#

The client is authenticated or identifiable, but does not have permission.

Example:

User → tries admin operation
       ↓
403 Forbidden

404 Not Found#

The requested resource cannot be found.

GET /users/999999

may return:

404 Not Found

405 Method Not Allowed#

The resource exists, but the HTTP method is not supported for it.


409 Conflict#

The request conflicts with the current state.

Example:

POST /users
 
email already exists

Could return:

409 Conflict

429 Too Many Requests#

The client exceeded a rate limit.

Example:

100 requests/minute allowed
 
Request #101
    ↓
429 Too Many Requests

21. Important 5xx Codes#

500 Internal Server Error#

Generic server-side failure.

502 Bad Gateway#

A gateway or proxy received an invalid response from an upstream server.

Example:

Client
  ↓
Load Balancer
  ↓
Application Server
  ↓
Application fails

The proxy may return 502 depending on what happened.

503 Service Unavailable#

The service is temporarily unavailable.

Possible causes:

  • overload
  • maintenance
  • unavailable dependency
  • temporary capacity issue

504 Gateway Timeout#

A gateway/proxy did not receive a timely response from an upstream service.


22. 401 vs 403#

A classic interview question.

Think:

401 → Who are you?
403 → I know who you are, but you cannot do this.

Example:

GET /admin/users

Without valid authentication:

401

Authenticated normal user attempting admin-only operation:

403

The exact security behavior can vary by API, but this is the standard mental model.


23. HTTP Headers#

Headers carry metadata.

Example:

Content-Type: application/json
Accept: application/json
Authorization: Bearer token
Cache-Control: max-age=3600
ETag: "abc123"
User-Agent: Mozilla/5.0

Important categories include:

  • representation headers
  • caching headers
  • authentication headers
  • security headers
  • connection-related metadata
  • tracing headers

24. Content-Type#

Content-Type tells the receiver what format the message body uses.

Example:

Content-Type: application/json

Other examples:

text/html
text/plain
application/xml
multipart/form-data
application/x-www-form-urlencoded

For a JSON API:

Content-Type: application/json

25. Accept#

Accept tells the server what response formats the client can process.

Example:

Accept: application/json

This is different from Content-Type.

Remember:

Content-Type
→ What format am I sending?
 
Accept
→ What format do I want back?

26. Authorization Header#

A common authentication pattern is:

Authorization: Bearer <token>

The server validates the token before allowing protected operations.

Typical flow:

Client
  ↓
Authorization header
  ↓
API Gateway / Application
  ↓
Validate token
  ↓
Authorize request

27. Cookies#

A cookie is data associated with a client and a website/domain.

Example:

Set-Cookie: session_id=abc123

The browser can later send:

Cookie: session_id=abc123

Cookies are commonly used for:

  • sessions
  • authentication
  • preferences
  • tracking
  • personalization

28. Cookie-Based Authentication#

A common flow:

1. User logs in
       ↓
2. Server validates credentials
       ↓
3. Server creates session
       ↓
4. Server sends session cookie
       ↓
5. Browser stores cookie
       ↓
6. Browser automatically sends cookie
       ↓
7. Server identifies session

Example:

Set-Cookie: session_id=abc123; HttpOnly; Secure; SameSite=Lax

29. Important Cookie Security Attributes#

HttpOnly#

Prevents JavaScript from directly reading the cookie.

Useful for reducing exposure to some forms of XSS-based cookie theft.

Secure#

Cookie should be transmitted over HTTPS.

SameSite#

Controls cross-site cookie behavior and can help mitigate certain CSRF scenarios.

Common values:

Strict
Lax
None

SameSite=None generally requires Secure.


30. Sessions#

A session allows a server to associate multiple requests with the same user.

A traditional architecture:

Browser
   ↓
Session Cookie
   ↓
Load Balancer
   ↓
Application Server
   ↓
Session Store

The session store may be:

Redis
Database
Distributed cache

31. Stateful Session Problem#

Imagine:

User
  ↓
Load Balancer
  ├── Server A
  └── Server B

The user logs in through Server A.

If the session exists only in Server A's memory:

Login
 ↓
Server A
 ↓
session stored in A memory

Then the next request goes to Server B:

Request
 ↓
Server B
 ↓
No session
 ↓
User appears logged out

This is one reason centralized or distributed session storage can be important.


32. Sticky Sessions#

One solution is session affinity.

User A → always Server A
User B → always Server B

This is commonly called:

Sticky sessions

It can work, but it creates trade-offs.

Problems can include:

  • uneven traffic distribution
  • reduced flexibility
  • difficult failover
  • state tied to specific instances

A more scalable design often keeps application servers stateless and stores shared state externally.


33. Stateless APIs#

In a stateless API:

Request
  ↓
Server
  ↓
Response

The server does not need local memory of the previous request to understand the current request.

Authentication information may be carried in each request, for example:

Authorization: Bearer <token>

Benefits:

  • easier horizontal scaling
  • easier load balancing
  • easier replacement of failed instances
  • simpler autoscaling

But statelessness does not mean the overall system has no state.

The state can live in:

Database
Redis
Object storage
External identity provider

34. REST API#

REST stands for:

Representational State Transfer

REST is an architectural style, not a protocol.

A REST-style API generally models resources.

For example:

/users
/users/123
/orders
/orders/456
/products
/products/10

35. Resource-Oriented API Design#

Instead of:

/getUser
/createUser
/updateUser
/deleteUser

a resource-oriented design commonly uses:

GET    /users/123
POST   /users
PUT    /users/123
PATCH  /users/123
DELETE /users/123

The HTTP method expresses the operation.

The URL identifies the resource.


36. Nested Resources#

Example:

/users/123/orders

This can represent orders belonging to user 123.

Another example:

/orders/456/items

Use nesting when the relationship is meaningful.

Avoid excessively deep URLs such as:

/users/1/orders/2/items/3/products/4/reviews/5

They can become difficult to maintain.


37. JSON#

JSON stands for:

JavaScript Object Notation

Example:

{
  "id": 123,
  "name": "Anubhav",
  "active": true
}

JSON is widely used in APIs because it is:

  • readable
  • compact enough for many applications
  • easy to parse
  • supported by many programming languages

38. API Response Design#

A response should have a predictable structure.

Example:

{
  "id": "123",
  "name": "Anubhav",
  "email": "user@example.com"
}

For an error:

{
  "error": {
    "code": "USER_NOT_FOUND",
    "message": "User does not exist"
  }
}

Consistency is more important than inventing a complex format.


39. Authentication vs Authorization#

These are different.

Authentication#

Answers:

Who are you?

Examples:

Password
OTP
Session
JWT
OAuth
API key

Authorization#

Answers:

What are you allowed to do?

Example:

User → read own profile
Admin → read all profiles

Flow:

Authentication
      ↓
Identity
      ↓
Authorization
      ↓
Permission

40. API Keys#

An API key is a credential commonly used to identify an application or client.

Example:

X-API-Key: abc123

Common uses:

  • service-to-service APIs
  • developer APIs
  • usage tracking
  • simple client identification

API keys should be treated as secrets when they provide privileged access.


41. JWT#

JWT stands for:

JSON Web Token

A JWT commonly contains:

Header
Payload
Signature

Conceptually:

header.payload.signature

A payload might contain claims such as:

{
  "sub": "123",
  "role": "user",
  "exp": 1790000000
}

Important:

A signed JWT is not automatically encrypted.

Sensitive information should not be placed in a JWT merely assuming the payload is secret.


42. JWT Request Flow#

User
 ↓
Login
 ↓
Authentication Server
 ↓
JWT
 ↓
Client
 ↓
Authorization: Bearer JWT
 ↓
API
 ↓
Validate signature + claims
 ↓
Authorize

JWTs can be useful for stateless authentication, but they introduce considerations around:

  • expiration
  • revocation
  • key rotation
  • token storage
  • refresh tokens
  • compromised credentials

43. OAuth#

OAuth is an authorization framework used to allow applications to access resources without requiring the user to share their password with the client application.

A simplified example:

User
 ↓
Application
 ↓
Authorization Server
 ↓
User grants permission
 ↓
Access Token
 ↓
Application
 ↓
Resource Server

For modern web authentication flows, OAuth 2.x and OpenID Connect are important topics.

OpenID Connect builds an identity layer on top of OAuth 2.0.


44. Idempotency#

Idempotency is one of the most important system design concepts.

Suppose a user makes a payment:

POST /payments

The network fails after the server processes the payment.

The client does not know whether payment succeeded.

It retries:

POST /payments

Without protection:

Payment 1 → ₹10,000
Payment 2 → ₹10,000

The customer may be charged twice.


45. Idempotency Keys#

A common solution is an idempotency key.

Client sends:

POST /payments
Idempotency-Key: 7b9f-payment-123

The server stores the result associated with that key.

First request:

Key = ABC
Payment processed
Result stored

Retry:

Key = ABC
       ↓
Existing result found
       ↓
Return previous result

Therefore:

Retry ≠ duplicate operation

46. Idempotency-Key Storage#

A simplified architecture:

Client
  ↓
API
  ↓
Idempotency Store
  ↓
Payment Service
  ↓
Database

The idempotency record might contain:

key
request fingerprint
status
response
created_at
expiration

The exact implementation must carefully handle concurrency.

Two identical requests can arrive at nearly the same time.

The system must avoid:

Request A → process payment
Request B → process same payment

47. Pagination#

Large datasets should not normally be returned in one response.

Bad:

GET /users

returning millions of users.

Instead:

GET /users?page=1&limit=20

or cursor-based pagination.


48. Offset Pagination#

Example:

GET /users?limit=20&offset=40

Meaning:

skip 40
return next 20

Advantages:

  • simple
  • easy to understand
  • convenient for many admin interfaces

Problems:

  • large offsets can become expensive
  • records can move between pages when data changes
  • consistency can be difficult for rapidly changing datasets

49. Cursor Pagination#

Example:

GET /users?limit=20&after=eyJpZCI6MTAw...

The cursor represents where to continue.

Conceptually:

Page 1
 ↓
last item = 100
 ↓
cursor = 100
 
Page 2
 ↓
items after 100

Cursor pagination is often better for large or frequently changing datasets.


50. Pagination Response#

Example:

{
  "data": [
    {
      "id": 101,
      "name": "A"
    },
    {
      "id": 102,
      "name": "B"
    }
  ],
  "next_cursor": "abc123",
  "has_more": true
}

51. Filtering#

APIs often support filtering.

Example:

GET /products?category=electronics

Multiple filters:

GET /products?category=electronics&min_price=1000&max_price=50000

Filters should have predictable semantics.


52. Sorting#

Example:

GET /products?sort=price

Descending:

GET /products?sort=-price

A production API should explicitly document supported fields rather than accepting arbitrary database fields.


53. Searching#

Example:

GET /products?q=iphone

For simple search this may be enough.

For large-scale search systems, a dedicated search engine can become appropriate.

Later in this course we will study search architecture in detail.


54. Rate Limiting#

Rate limiting controls how many requests a client can make during a period.

Example:

100 requests / minute

If the client exceeds the limit:

429 Too Many Requests

Rate limiting protects:

  • APIs
  • databases
  • downstream services
  • infrastructure
  • cost
  • availability

55. Why Rate Limiting Matters in System Design#

Imagine an API has:

10 application servers
1 database

A malicious or buggy client sends:

100,000 requests/sec

Even if application servers can process some of the traffic, the database may collapse.

Rate limiting creates a protective boundary.

Internet
   ↓
API Gateway
   ↓
Rate Limiter
   ↓
Application
   ↓
Database

56. Common Rate-Limiting Algorithms#

Important algorithms include:

Fixed Window#

12:00–12:01
100 requests allowed

Simple, but boundary bursts can occur.

Sliding Window#

Tracks requests over a moving time range.

More accurate, but potentially more expensive.

Token Bucket#

Tokens accumulate up to a maximum capacity.

Requests consume tokens.

Token Bucket
 ├── token
 ├── token
 ├── token
 └── token

Useful because it can allow controlled bursts.

Leaky Bucket#

Requests are processed at a controlled rate.

Useful for smoothing traffic.

We will study these algorithms in greater detail later.


57. Where Should Rate Limiting Happen?#

Possible locations:

CDN
 ↓
API Gateway
 ↓
Load Balancer
 ↓
Application

Rate limiting can be:

  • per IP
  • per user
  • per API key
  • per tenant
  • per endpoint
  • global

Distributed systems often use Redis or another shared store when multiple API instances need consistent rate-limit state.


58. API Versioning#

APIs evolve.

Suppose version 1 returns:

{
  "name": "Anubhav"
}

Version 2 changes it to:

{
  "first_name": "Anubhav",
  "last_name": "Chaudhary"
}

Existing clients may break.

Versioning helps manage compatibility.


59. URL Versioning#

Example:

/api/v1/users
/api/v2/users

Easy to understand and commonly used.


60. Header-Based Versioning#

Another approach:

Accept: application/vnd.example.v2+json

This keeps versioning out of the URL but increases complexity.

There are multiple legitimate strategies.

The important system design concern is:

How do we evolve an API without unexpectedly breaking existing clients?


61. Backward Compatibility#

Good API evolution often follows:

Old client
     ↓
Existing API behavior remains valid
     ↓
New functionality added
     ↓
Old behavior deprecated gradually

Avoid breaking clients without a migration strategy.

Potential strategies:

  • additive changes
  • versioning
  • deprecation periods
  • migration documentation
  • compatibility layers

62. API Gateway#

A large system may place an API gateway in front of services.

                  ┌── User Service
Client
   ↓              ├── Order Service
API Gateway ──────┼── Payment Service
                  └── Notification Service

The gateway may handle:

  • authentication
  • authorization
  • rate limiting
  • routing
  • request validation
  • TLS termination
  • logging
  • metrics
  • API version routing

We will study API gateways more deeply later.


63. Reverse Proxy vs API Gateway#

These concepts overlap but are not identical.

A reverse proxy generally forwards client requests to backend servers.

An API gateway is often a more application/API-aware entry point that can provide:

  • authentication
  • routing
  • rate limiting
  • transformation
  • policy enforcement
  • API-specific observability

A reverse proxy can perform some of these functions too.


64. Request Timeout#

Never assume every backend request will finish quickly.

Example:

Client
 ↓
API Gateway
 ↓
Service A
 ↓
Service B
 ↓
Database

If Service B hangs:

Service A waits
Gateway waits
Client waits

Eventually resources can be exhausted.

Therefore APIs should have explicit timeouts.

Example:

Client timeout: 10s
Gateway timeout: 8s
Service timeout: 5s
Database timeout: 2s

The exact values depend on the system.


65. Retries#

Retries can improve reliability when failures are transient.

Example:

Request
 ↓
503
 ↓
wait
 ↓
retry

But retries can also make an outage worse.

Suppose:

Service overloaded
     ↓
100 requests fail
     ↓
each client retries 3 times
     ↓
300 additional requests

This is called a retry storm.

Use:

  • bounded retries
  • exponential backoff
  • jitter
  • retry only appropriate failures
  • idempotency where needed

66. Exponential Backoff#

Instead of retrying immediately:

Retry 1 → 100 ms
Retry 2 → 200 ms
Retry 3 → 400 ms
Retry 4 → 800 ms

Jitter adds randomness:

100 ms + random
200 ms + random
400 ms + random

This helps avoid many clients retrying at exactly the same time.


67. HTTP Caching#

HTTP supports caching.

Example:

Cache-Control: max-age=3600

The client or intermediary can reuse the response for the specified period.

Caching can happen at:

Browser
 ↓
CDN
 ↓
Reverse Proxy
 ↓
Application Cache

68. ETag#

An ETag identifies a particular representation.

Example:

ETag: "abc123"

The client later sends:

If-None-Match: "abc123"

If nothing changed:

304 Not Modified

This saves bandwidth.


69. Conditional Requests#

The general pattern:

First request
 ↓
200 + ETag
 ↓
Client stores response
 
Later request
 ↓
If-None-Match
 ↓
Server checks version
 ↓
304

This is particularly useful for frequently requested resources that do not change often.


70. Compression#

Large HTTP responses can be compressed.

Common compression methods include:

gzip
Brotli

Compression reduces network bandwidth but costs CPU.

The client can advertise support using:

Accept-Encoding: gzip, br

The server can respond with:

Content-Encoding: br

System design trade-off:

CPU cost
    ↕
Network bandwidth

71. Request Correlation IDs#

Distributed systems need a way to trace one request across services.

Example:

X-Request-ID: 7f82abc123

Request:

Client
 ↓ request-id=7f82
Gateway
 ↓
Service A
 ↓
Service B
 ↓
Database

Logs can include:

request_id=7f82

This makes debugging much easier.

Later we will study distributed tracing and observability in depth.


72. API Error Design#

Bad:

{
  "error": "bad"
}

Better:

{
  "error": {
    "code": "INVALID_EMAIL",
    "message": "The email address is invalid"
  }
}

For validation errors, structured details can help:

{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "Request validation failed",
    "fields": {
      "email": "Invalid email format"
    }
  }
}

Do not expose:

  • database passwords
  • internal stack traces
  • secrets
  • internal infrastructure details

73. API Security Basics#

An API should consider:

Authentication#

Who is calling?

Authorization#

What can they access?

Input validation#

Is the input valid?

Rate limiting#

Is the caller sending too many requests?

TLS#

Is communication encrypted?

Secret management#

Are credentials protected?

Logging#

Are security events observable?

Least privilege#

Does the identity have only required permissions?


74. Input Validation#

Never blindly trust client input.

Example:

{
  "age": "hello"
}

If the API expects an integer, reject it.

Validation should happen before expensive operations.

Request
 ↓
Authentication
 ↓
Authorization
 ↓
Validation
 ↓
Business logic
 ↓
Database

The exact ordering can vary, but untrusted input should be validated before use.


75. API Payload Size Limits#

A malicious client might send:

POST /upload
Body = 10 GB

Without limits, this can consume memory, bandwidth, storage, or CPU.

Production APIs often enforce:

  • maximum request body size
  • maximum upload size
  • maximum JSON depth/complexity where relevant
  • timeout
  • maximum number of items in a request

76. API Design Example — User Service#

Suppose we are designing a user API.

Create user#

POST /api/v1/users

Get user#

GET /api/v1/users/123

Update user#

PATCH /api/v1/users/123

Delete user#

DELETE /api/v1/users/123

List users#

GET /api/v1/users?limit=20&after=abc

This is much easier to reason about than arbitrary action-based endpoints.


77. API Design Example — Orders#

POST   /api/v1/orders
GET    /api/v1/orders/123
PATCH  /api/v1/orders/123
DELETE /api/v1/orders/123
GET    /api/v1/users/42/orders

For an operation that is not naturally CRUD, an action endpoint can sometimes be appropriate.

For example:

POST /api/v1/orders/123/cancel

The goal is not to force every business operation into CRUD.

The goal is to make the API semantics clear and consistent.


78. Synchronous vs Asynchronous APIs#

Some operations finish quickly:

POST /users
 ↓
201 Created

Other operations take a long time:

POST /videos/123/transcode

Instead of keeping the request open for minutes:

POST
 ↓
202 Accepted
 ↓
job created

Then:

GET /jobs/456

returns:

{
  "id": "456",
  "status": "processing"
}

Later:

{
  "id": "456",
  "status": "completed"
}

This pattern is common in distributed systems.


79. Webhooks#

Sometimes the server needs to notify another system when something happens.

Example:

Payment Service
      ↓
Payment completed
      ↓
Webhook
      ↓
Merchant Application

Example:

POST https://merchant.example/webhooks/payment

The webhook body may contain:

{
  "event": "payment.completed",
  "payment_id": "pay_123",
  "amount": 1000
}

Webhook systems need:

  • authentication/signatures
  • retries
  • idempotency
  • event IDs
  • timeout handling
  • duplicate delivery handling

80. API Design and Database Design#

API design should not simply expose database tables.

Bad mental model:

Database table
      ↓
Directly expose table

Instead:

API
 ↓
Domain / business logic
 ↓
Data access
 ↓
Database

Why?

Because the database schema may change without wanting to break clients.

The API should represent a stable business contract.


81. API Contract#

An API contract defines how clients and servers communicate.

It can specify:

  • endpoints
  • methods
  • parameters
  • request schemas
  • response schemas
  • error formats
  • authentication
  • status codes
  • pagination
  • rate limits

OpenAPI is commonly used to describe HTTP APIs.

Example conceptual contract:

GET /users/{id}
 
Response:
{
  id: string,
  name: string,
  email: string
}

82. API Gateway + Rate Limiter + Services#

A typical production architecture may look like:

                         ┌── User Service
                         │
Client
  ↓                      ├── Order Service
CDN / Edge
  ↓                      │
API Gateway
  ↓                      ├── Payment Service
Auth + Rate Limit + Logs │
                         └── Notification Service

Each service may have its own:

Cache
Database
Queue

The gateway provides a controlled entry point.


83. API Latency Budget#

Suppose the API has a target:

P95 latency < 300 ms

The request may spend time in:

Gateway       10 ms
Service A     40 ms
Cache         10 ms
Database      80 ms
Service B     60 ms
Network       30 ms
--------------------
Total         230 ms

The remaining budget is:

300 - 230 = 70 ms

System designers should think in terms of latency budgets rather than optimizing one component in isolation.


84. P50, P95, P99#

Average latency can hide bad user experiences.

Suppose:

Average = 100 ms

But:

P50 = 70 ms
P95 = 300 ms
P99 = 2 seconds

Then 1% of requests are taking around seconds.

For large systems, tail latency matters greatly.

We will study performance engineering later.


85. Common HTTP/API Mistakes#

Mistake 1 — Treating HTTP as the entire network#

HTTP sits at the application layer.

HTTP
 ↓
TCP/QUIC
 ↓
IP

Mistake 2 — Confusing 401 and 403#

Remember:

401 → authentication problem
403 → permission problem

Mistake 3 — Assuming POST retries are safe#

POST may create duplicates.

Use idempotency mechanisms for operations where retries must not duplicate effects.


Mistake 4 — Returning huge datasets#

Use:

  • pagination
  • filtering
  • limits

Mistake 5 — No timeout#

Every network call can potentially hang.

Use explicit timeouts.


Mistake 6 — Blind retries#

Retries can amplify outages.

Use:

  • exponential backoff
  • jitter
  • bounded retries
  • appropriate retry policies

Mistake 7 — Storing session state only in local memory#

Horizontal scaling can break this design.

Use shared state or stateless authentication where appropriate.


Mistake 8 — Putting sensitive information in JWT payloads#

A signed JWT is not automatically encrypted.


Mistake 9 — Exposing internal errors#

Do not return stack traces or infrastructure secrets to clients.


Mistake 10 — Designing API URLs around database tables#

An API is a business-facing contract, not necessarily a direct mirror of storage.


86. Beginner Mental Model vs Technical Reality#

Beginner mental model#

Browser
 ↓
HTTP
 ↓
Server

More realistic system#

Browser
 ↓
DNS
 ↓
CDN
 ↓
TLS
 ↓
Load Balancer
 ↓
API Gateway
 ↓
Authentication
 ↓
Rate Limiter
 ↓
Service
 ↓
Cache
 ↓
Database
 ↓
Queue / Other Services

The more advanced system introduces many possible failure and latency points.

System design is largely about controlling those points.


87. Interview Questions#

Q1. What happens when a browser sends an HTTP request?#

A strong answer:

DNS resolution
 ↓
Connection establishment
 ↓
TLS for HTTPS
 ↓
HTTP request
 ↓
CDN / reverse proxy / load balancer
 ↓
Application
 ↓
Cache/database/dependencies
 ↓
HTTP response
 ↓
Browser processes response

Q2. GET vs POST?#

GET is normally used to retrieve resources.

POST is commonly used to create resources or trigger operations.

POST is generally not idempotent.


Q3. PUT vs PATCH?#

PUT generally replaces a resource representation.

PATCH generally applies partial modifications.


Q4. 401 vs 403?#

401 → authentication required/failed
403 → authenticated/identified but not allowed

Q5. Why use pagination?#

To avoid transferring and processing enormous datasets in one request.


Q6. Offset vs cursor pagination?#

Offset is simple but can become inefficient and unstable for changing large datasets.

Cursor pagination is generally more suitable for large, frequently changing datasets.


Q7. Why is idempotency important in payment APIs?#

Because network failures can cause clients to retry requests after the server has already processed them.

An idempotency key allows the server to recognize the retry and avoid duplicating the operation.


Q8. Why use an API gateway?#

It can centralize:

  • routing
  • authentication
  • authorization
  • rate limiting
  • TLS termination
  • observability
  • API policies

Q9. Why are timeouts important?#

Without timeouts, blocked dependencies can consume connections, threads, workers, and other resources until the system becomes overloaded.


Q10. Why can retries be dangerous?#

Because retries increase traffic during failures and can amplify an outage.


88. Practical Exercise#

Design a REST API for a simple task-management application.

Requirements:

  • create task
  • get task
  • update task
  • delete task
  • list tasks
  • filter by status
  • pagination
  • authentication

Try to design:

POST   /api/v1/...
GET    /api/v1/...
PATCH  /api/v1/...
DELETE /api/v1/...

Also decide:

  • status codes
  • request JSON
  • response JSON
  • authentication method
  • pagination strategy
  • error format
  • rate limit
  • timeout

89. Mini Project — Production-Style Task API#

Design the following:

Client
  ↓
API Gateway
  ↓
Task Service
  ↓
PostgreSQL

Add:

Authentication
Rate Limiting
Pagination
Request Validation
Error Handling
Idempotency
Logging

Example endpoints:

POST   /api/v1/tasks
GET    /api/v1/tasks
GET    /api/v1/tasks/{id}
PATCH  /api/v1/tasks/{id}
DELETE /api/v1/tasks/{id}

List endpoint:

GET /api/v1/tasks?status=pending&limit=20&after=abc

Create response:

201 Created

Invalid request:

400 Bad Request

Unauthenticated:

401 Unauthorized

Not permitted:

403 Forbidden

Not found:

404 Not Found

Rate limited:

429 Too Many Requests

Unexpected server failure:

500 Internal Server Error

90. Chapter Summary#

You should now understand:

HTTP#

  • HTTP request/response model
  • HTTP versions
  • request line
  • headers
  • body
  • response status
  • HTTP methods

Status Codes#

  • 2xx
  • 3xx
  • 4xx
  • 5xx
  • important individual status codes

State and Authentication#

  • cookies
  • sessions
  • stateful applications
  • stateless APIs
  • API keys
  • JWT
  • OAuth concepts
  • authentication vs authorization

API Design#

  • REST
  • resources
  • CRUD
  • JSON
  • filtering
  • sorting
  • searching
  • pagination
  • API versioning
  • backward compatibility
  • API contracts

Production Concerns#

  • idempotency
  • idempotency keys
  • rate limiting
  • timeouts
  • retries
  • exponential backoff
  • jitter
  • caching
  • ETags
  • compression
  • request IDs
  • payload limits
  • validation
  • API security
  • webhooks
  • synchronous vs asynchronous APIs

91. The Big Picture#

We can now connect the first four chapters:

                    SYSTEM DESIGN
 
User
 │
 ▼
Browser / Mobile App
 │
 │ DNS
 ▼
IP Address
 │
 │ TCP / QUIC
 ▼
Network Connection
 │
 │ TLS
 ▼
Secure Connection
 │
 │ HTTP
 ▼
CDN / Reverse Proxy / Load Balancer
 │
 ▼
API Gateway
 │
 ├── Authentication
 ├── Authorization
 ├── Rate Limiting
 └── Routing
 │
 ▼
Application Service
 │
 ├── Cache
 ├── Database
 ├── Queue
 └── Other Services
 │
 ▼
HTTP Response

This is the foundation on which the rest of system design will be built.


92. Chapter 04 Master Checklist#

Before moving on, make sure you can explain:

  • What HTTP is
  • HTTP request structure
  • HTTP response structure
  • HTTP/1.1 vs HTTP/2 vs HTTP/3
  • GET vs POST
  • PUT vs PATCH
  • Safe methods
  • Idempotent methods
  • 200 vs 201 vs 202 vs 204
  • 301 vs 304
  • 400 vs 401 vs 403 vs 404
  • 409 vs 429
  • 500 vs 502 vs 503 vs 504
  • Content-Type vs Accept
  • Cookies
  • Sessions
  • Sticky sessions
  • Stateless APIs
  • REST
  • JSON
  • Authentication
  • Authorization
  • JWT
  • OAuth
  • Idempotency keys
  • Offset pagination
  • Cursor pagination
  • Rate limiting
  • Token bucket
  • API versioning
  • Timeouts
  • Retries
  • Exponential backoff
  • Jitter
  • HTTP caching
  • ETag
  • API gateway
  • Request IDs
  • API security
  • Webhooks
  • Synchronous vs asynchronous APIs

93. What Comes Next?#

Chapter 05 — Servers & Application Architecture#

In the next chapter, we move from how HTTP communicates with an application to how the application itself is structured and deployed.

We will learn:

Web Server
      ↓
Application Server
      ↓
Process
      ↓
Thread / Worker
      ↓
Request Handling
      ↓
Application Architecture

We will cover:

  • what a server really is
  • web servers vs application servers
  • processes and threads
  • workers
  • connection pools
  • synchronous vs asynchronous processing
  • stateless application servers
  • reverse proxies
  • application tiers
  • monolith basics
  • request lifecycle inside a server
  • graceful shutdown
  • health checks
  • horizontal scaling preparation
  • server bottlenecks
  • production server architecture

Then we will be ready to study scaling applications in Chapter 06.

Finished this chapter?

Mark it as complete to track your mastery.

Previous ChapterChapter 03 — DNS Deep DiveNext ChapterChapter 05 — Servers & Application Architecture
PrevNext