LibraryLearning
Back to course

Internet and Request Flow • Lesson 3

How HTTP Works

20 minute lesson

Learning objectives

  • Understand request-response structure
  • Learn what methods, headers, and status codes actually do
  • Improve API intuition

What Is It?

HTTP (HyperText Transfer Protocol) is the protocol that powers the web. Every time a browser loads a page, submits a form, or calls an API, it's using HTTP. It defines a simple, text-based format: the client sends a request, the server sends a response. That's the entire model.

HTTP is stateless — every request is independent. The server has no memory of previous requests unless you explicitly pass state along (via cookies, tokens, or session IDs). This simplicity is what made HTTP so successful: it scales horizontally because any server can handle any request without knowing the history.

HTTP has gone through three major versions — HTTP/1.1 (1997), HTTP/2 (2015), and HTTP/3 (2022) — each addressing performance limitations of the previous. Most developers work at the HTTP/1.1 conceptual level even when their servers run HTTP/2 underneath, because the concepts are the same; the transport layer just got faster.

How It Actually Works

The Request

An HTTP request has three parts: a request line, headers, and an optional body.

POST /api/login HTTP/1.1
Host: example.com
Content-Type: application/json
Authorization: Bearer abc123
Content-Length: 42

{"email": "user@example.com", "password": "hunter2"}

Breaking this down:

  • POST — the method (what kind of action)
  • /api/login — the path (which resource)
  • HTTP/1.1 — the protocol version
  • Headers — key-value metadata about the request
  • Blank line — separates headers from body
  • Body — the actual data being sent (optional, not in GET requests)

The Response

HTTP/1.1 200 OK
Content-Type: application/json
Set-Cookie: session=xyz; HttpOnly; Secure
Content-Length: 89

{"token": "eyJhbGciOiJIUzI1NiJ9...", "user": {"id": 1, "email": "user@example.com"}}
  • Status line: protocol version + status code + reason phrase
  • Headers: metadata about the response
  • Body: the actual content

HTTP Methods

Methods define the intent of the request:

Method Intent Has Body?
GET Retrieve a resource No
POST Submit data, create something Yes
PUT Replace a resource entirely Yes
PATCH Partially update a resource Yes
DELETE Remove a resource No
HEAD Like GET but only return headers No
OPTIONS Ask what methods are supported No

Methods are a convention — the server can technically handle a GET request however it likes. REST APIs use them to signal intent, but nothing enforces this at the protocol level.

Status Codes

Status codes are grouped by their first digit:

  • 1xx — Informational (rarely seen — 100 Continue tells a client to keep sending a large body)
  • 2xx — Success (200 OK, 201 Created, 204 No Content)
  • 3xx — Redirection (301 Moved Permanently, 302 Found, 304 Not Modified)
  • 4xx — Client error (400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 429 Too Many Requests)
  • 5xx — Server error (500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable)

The most important distinction: 4xx means you did something wrong. 5xx means the server did something wrong.

HTTP/1.1 vs HTTP/2 vs HTTP/3

The semantics (methods, headers, status codes) are the same across all versions. What changed is the transport:

HTTP/1.1: One request at a time per connection. To send 10 requests in parallel, browsers open 6-8 TCP connections. Slow and wasteful.

HTTP/2: Multiplexing — multiple requests over a single TCP connection simultaneously. Also adds header compression (HPACK) and server push. Same HTTP semantics, much faster.

HTTP/1.1:
Request 1 → Response 1 → Request 2 → Response 2 (sequential)

HTTP/2:
Request 1 ┐               ┌ Response 1
Request 2 ├─ same TCP ───►├ Response 2  (multiplexed, parallel)
Request 3 ┘               └ Response 3

HTTP/3: Replaces TCP with QUIC (a UDP-based protocol). Solves "head-of-line blocking" in HTTP/2 — if one packet is lost in a TCP connection, all requests stall waiting for retransmission. QUIC handles packet loss per-stream. Also has faster connection establishment (0-RTT for known servers).

The Jargon Decoded

  • Request/Response — The fundamental HTTP pattern. Client sends a request, server sends exactly one response. Unlike WebSockets, this is always one-way initiated by the client.
  • Header — Key-value metadata attached to requests and responses. Content-Type, Authorization, Cache-Control are all headers. They're text, not binary.
  • CORS (Cross-Origin Resource Sharing) — A browser security mechanism that blocks JavaScript from making requests to different domains unless the server explicitly permits it via Access-Control-Allow-Origin headers.
  • Idempotent — An operation is idempotent if doing it multiple times has the same result as doing it once. GET, PUT, DELETE are idempotent. POST is not. Important for retry logic.
  • Keep-Alive — HTTP/1.1 feature that reuses a TCP connection for multiple requests instead of opening a new one each time.
  • Cache-Control — Header that tells browsers and CDNs how long to cache a response. max-age=3600 means cache for 1 hour. no-cache means always revalidate.
  • MIME Type / Content-Type — Tells the receiver what kind of data is in the body. application/json, text/html, image/png, etc.
  • TLS/HTTPS — HTTP running over an encrypted channel. The HTTP protocol itself doesn't change — the transport layer gets encrypted.

Why This Matters When You're Building

HTTP is the foundation of every API your vibe-coded app talks to. When something breaks, you need to know:

  • Is it a 4xx (your app sent a bad request) or 5xx (the API is broken)?
  • Are you setting Content-Type: application/json correctly, or is the server receiving your body as a string?
  • Are CORS errors blocking your frontend from reaching your backend? (This is a browser enforcement issue, not a network issue — the request does reach the server.)
  • Is a 304 Not Modified from a CDN serving stale data?

When you instruct AI to "fix my API call", the more you can say about the exact request and response (method, path, headers, status code, body), the better the fix will be.

HTTP/2 matters when you're choosing a hosting setup or debugging performance. If you're serving 40 small assets on page load, HTTP/1.1 becomes a bottleneck. Modern hosts (Vercel, Cloudflare, Nginx configured correctly) use HTTP/2 by default.

What To Tell The AI

"My API call is returning 401. Here's the exact request I'm making [paste code]. Diagnose whether this is a missing Authorization header, expired token, wrong token format, or something else — and how to tell which."

"My frontend at localhost:3000 is getting CORS errors trying to reach my backend at localhost:8080. Explain exactly what's happening and write the exact headers my Express server needs to respond with."

"I'm building a REST API. For each of these operations — create user, get user by ID, update user's email, delete user — tell me the correct HTTP method and path I should use, and why."

"My app makes 20 HTTP requests on page load. Explain how HTTP/2 multiplexing changes the strategy vs HTTP/1.1, and whether I should still bundle my JavaScript given that."

"Explain the difference between 401 and 403 in practical terms, and when I should return each one from my API. My app has both unauthenticated requests and authenticated-but-unauthorised requests."

Common Misconceptions

"GET requests can't have a body." Technically they can send one, but servers and intermediaries typically ignore it, and it's against the spec's intent. Never send data in a GET body — use query parameters (?key=value) or switch to POST. Some ORMs and API clients silently drop GET bodies.

"POST is for creating, PUT is for updating." This is a REST convention, not an HTTP rule. HTTP itself doesn't care. The actual difference: PUT should be idempotent (calling it 5 times has the same result as calling it once). POST is not idempotent — submitting a form 5 times might create 5 records.

"CORS is a server-side security feature." CORS is enforced by browsers, not servers. If you make the same request from curl or Postman, CORS doesn't apply — you'll get the response fine. CORS only blocks JavaScript in a browser from reading responses across origins. The server receives the request regardless.

"A 200 OK means everything worked." Many APIs return 200 OK with an error message in the body (e.g., {"error": "invalid token"}). This is bad API design, but it's common. You need to check both the status code and the response body. Never assume a 200 means your operation succeeded.

Sources

  • MDN Web Docs — HTTP Overview — Definitive reference with examples for every concept
  • High Performance Browser Networking — Chapter 9: HTTP/1.X — Deep dive into HTTP/1.1 performance characteristics
  • High Performance Browser Networking — Chapter 12: HTTP/2 — How multiplexing actually works
  • HTTP/3 Explained — Daniel Stenberg's free book on QUIC and HTTP/3
  • RFC 7231 — HTTP/1.1 Semantics and Content — The spec for methods, headers, and status codes

Checkpoint questions

  • What is the minimum mental model for an HTTP request?
  • Why do headers matter more than beginners think?

Exercise

Inspect one real API request in devtools and explain each major part.

Memory recall

Quick quiz

Use retrieval, not rereading. Answer from memory, then check the feedback.

1. What is the minimum useful mental model of an HTTP request?

2. Why do headers matter more than beginners think?

3. What does an HTTP status code tell you?

Progress

Mark this lesson complete when done

Next lesson