🌐 HTTP 101

The request/response model that every version shares — methods, headers, status codes, and why HTTP forgets you the moment it answers.

The Core Idea

HTTP is a request/response protocol. A client opens a connection to a server, sends one request, and the server sends back exactly one response. That's the whole contract. Everything else — REST APIs, web pages, gRPC, file downloads — is built on top of this one exchange.

sequenceDiagram participant C as Client (browser / app) participant S as Server C->>S: Request (method + path + headers + body) Note right of S: parse, route, do work S->>C: Response (status + headers + body) Note over C,S: connection may stay open for the next request
The request/response shape never changed. HTTP/1.1, /2, and /3 all carry the same semantics — methods, headers, status codes. What changed underneath is how the bytes travel: text vs binary frames, one request at a time vs many multiplexed. Learn the semantics once; they outlive every version bump.

Anatomy of a Request

An HTTP/1.1 request on the wire is plain text — you can read and type it by hand:

GET /users/42 HTTP/1.1
Host: api.example.com
Accept: application/json
Authorization: Bearer eyJhbGc...
User-Agent: curl/8.0

Anatomy of a Response

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 38
Cache-Control: max-age=60

{"id":42,"name":"Ada","active":true}

The status line leads with a three-digit code, then the same header/blank-line/body structure as a request. Content-Length tells the client exactly how many body bytes to read — critical when the connection stays open for the next request.

The Methods (Verbs)

MethodIntentSafe?Idempotent?
GETRead a resourceYesYes
POSTCreate / trigger an actionNoNo
PUTReplace a resource wholesaleNoYes
PATCHPartially updateNoNo
DELETERemove a resourceNoYes
HEADLike GET, headers onlyYesYes
OPTIONSAsk what's allowed (CORS preflight)YesYes
Safe = no server-side effect (caches and crawlers rely on this). Idempotent = sending it twice lands the same state as once. Idempotency is what makes automatic retries safe — a dropped PUT can be resent; a dropped POST might double-charge a card.

Status Codes

The leading digit is the whole story; the rest is detail.

ClassMeaningCommon members
1xxInformational100 Continue, 101 Switching Protocols
2xxSuccess200 OK, 201 Created, 204 No Content
3xxRedirect301 Moved, 304 Not Modified
4xxClient error400, 401, 403, 404, 429
5xxServer error500, 502, 503, 504
Classic confusion: 401 Unauthorized actually means unauthenticated (who are you?), while 403 Forbidden means authenticated but not allowed (I know you, and no). The names lie; the semantics don't.

Statelessness

HTTP has no memory. Each request is interpreted in complete isolation — the server does not inherently know that request B came from the same client as request A.

This is a deliberate design choice: it lets any server in a pool answer any request, which is what makes horizontal scaling and CDNs possible. State is bolted on above the protocol:

Keep the mental model clean: the connection can be long-lived (keep-alive), but the protocol semantics are still stateless. Reusing a socket is an optimization, not a session.

The URL

Every request targets a URL, and each part routes the bytes somewhere specific:

https://api.example.com:443/v1/users?active=true#top
└─┬─┘   └──────┬───────┘└┬┘└───┬────┘└────┬─────┘└┬┘
scheme      host       port   path      query   fragment

Key Takeaways

Real-world: when you debug a flaky API, you're almost always working at this layer — a wrong method, a missing Host, a 401 you expected to be a 403, a cache serving a stale 200. The version underneath (/1.1, /2, /3) rarely changes the semantics you're reasoning about — only the performance.

Next: HTTP/1.1 — how these semantics were originally carried as plain text, and the performance wall that text hit.