Skip to content
RungsySign in

HTTP: Requests & Responses

A stateless text protocol — understand its shape and half of backend work stops being mysterious.

35 minDifficulty 1/5fundamentals · protocolReviewedRead and accepted by a person.

Before this

Why this exists

Almost everything you'll build sends or receives HTTP. Yet most developers learn it by osmosis — absorbing enough to make `fetch` work and never seeing the shape underneath. Spend forty minutes on the actual structure and a surprising amount of backend work stops being guesswork: CORS errors, caching bugs, auth failures and mysterious 400s all become readable.

The mental model

A letter. There's an envelope with an address and handling instructions on the outside (the request line and headers), and there's whatever you put inside (the body). The recipient replies with a letter of the same shape.

How it works

It's text, and you can read it

An HTTP request is plain text in a fixed layout: a request line, then headers one per line, then a blank line, then an optional body. That's it. Everything your framework does — routing, parsing, content negotiation — is manipulation of this structure. Once you've seen a raw request, the abstractions above it stop being magic.

It is stateless, and that is a deliberate choice

The server is not required to remember anything between two requests. Each one arrives carrying everything needed to handle it. This feels like a limitation and is actually the reason the web scales: any server can handle any request, so you can put ten machines behind a load balancer without them coordinating. Sessions, cookies and tokens all exist to *simulate* memory on top of a protocol that deliberately has none.

The response mirrors the request

A response is the same shape: a status line with a code, then headers, then a blank line, then the body. The status code is the summary — the one thing a caller can act on without parsing anything else. The headers describe the body and how to treat it: what type it is, how long to cache it, whether it's compressed.

Connections are reused, versions matter less than you'd think

Opening a TCP connection is expensive, so HTTP/1.1 keeps them alive and sends many requests over one. HTTP/2 goes further and multiplexes many requests over a single connection simultaneously, removing the head-of-line blocking that made people shard assets across domains. HTTP/3 swaps TCP for QUIC. For application code, the semantics — methods, status codes, headers — are identical across all three. The version changes performance characteristics, not what you write.

The mechanism

A raw exchange, in full: ``` GET /users/42 HTTP/1.1 Host: api.example.com Accept: application/json Authorization: Bearer eyJhbGci... ``` ``` HTTP/1.1 200 OK Content-Type: application/json Cache-Control: private, max-age=60 Content-Length: 47 {"id":42,"name":"Ada","email":"ada@example.com"} ``` The blank line is load-bearing: it's the only thing separating headers from body.

sequenceDiagram
    participant B as Client
    participant S as Server
    B->>S: GET /users/42 HTTP/1.1
    Note over B,S: Host, Accept, Authorization headers
    S->>S: route, authorise, fetch
    S-->>B: HTTP/1.1 200 OK
    Note over B,S: Content-Type, Cache-Control, body
    B->>S: GET /users/42/orders (same connection)
    S-->>B: 200 OK
Diagram source for HTTP: Requests & Responses.

What people get wrong

HTTP and HTML are closely related.
HTTP is a transfer protocol; it neither knows nor cares what it's carrying. HTML is one payload among many. The protocol moves bytes and describes them with Content-Type. JSON, images and video all travel identically.
Each request opens a new connection.
Connections are kept alive and reused by default since HTTP/1.1. TCP setup plus TLS handshake costs multiple round trips, which would dominate the cost of small requests.
Statelessness means you can't have logged-in users.
It means the state travels with each request, in a cookie or token, rather than living implicitly on one server. Moving the state into the request is what lets any server handle any request.
HTTP/2 changes how I write my API.
The semantics are unchanged. Methods, status codes and headers work exactly the same. HTTP/2 changes framing and transport efficiency, not meaning. Some old workarounds like domain sharding become counterproductive, but your handler code is untouched.

When not to use it

You need the server to push data at any moment without the client asking.
WebSockets or Server-Sent Events. Plain HTTP is request-response — the client must initiate.
You need very low-latency, high-frequency messaging between your own internal services.
gRPC or a message queue. HTTP's per-request overhead and text headers are real costs at that volume.

Terms

Request line
The first line of a request: method, path, and protocol version.
Header
A key-value pair carrying metadata about the message — never the content itself.
Body
The actual payload. Optional; GET requests normally have none.
Stateless
The server keeps no memory of previous requests. Everything needed arrives with each one.
Keep-alive
Reusing one TCP connection for multiple requests instead of reconnecting each time.
Content-Type
The header declaring what format the body is in, so the recipient knows how to parse it.

In an interview

What happens when you type a URL and press enter?

  • DNS resolves the hostname to an IP address
  • TCP connection, then a TLS handshake for HTTPS
  • an HTTP request is sent: request line, headers, blank line, optional body
  • the server responds with a status code, headers and body
  • the browser parses and fetches subresources over the same reused connection

Why is HTTP stateless, and what does that cost you?

  • any server can serve any request, so horizontal scaling needs no coordination
  • the cost is that identity must travel with every request
  • cookies, sessions and tokens exist to reintroduce the state that was removed

Can you recall it?

Describe the structure of an HTTP request from memory, and say why statelessness matters.

Sources

Keep track of this

Add HTTP Semantics to your map and Rungsy will schedule reviews so you actually remember it.