HTTP / LESSON 09

HTTP is stateless

Understand why servers forget each request, and how logins work anyway.

An HTTP server handles each request on its own. It doesn't need to remember the previous request to understand this one. This property is called statelessness, and it's one of the main reasons that HTTP scales so well.

Each request stands alone

Compare a phone call with a series of letters:

  • On a phone call, you can say "and what about the other one?" The other person remembers the conversation.
  • In a letter, you have to say everything the reader needs. They may not have your last letter at hand.

HTTP works like letters. Look at these two requests:

The second request doesn't depend on the first. You can send them in any order, from different computers, and to different servers. There's no "next contact" request, because the server doesn't keep track of where you are.

Stateless doesn't mean that nothing is stored

When you created a contact, the server stored it. So what does HTTP forget?

Example Kept by the server?
Resource state The contacts in the address book Yes
Conversation state Which contact you looked at last No

The server remembers the data, but not the conversation.

What statelessness gives you

  • Scaling: any server behind a load balancer can answer any request.
  • Recovery: if a server restarts, clients can just send their next request.
  • Caching: a response can be reused, since it depends only on the request.
  • Debugging: you can reproduce a problem from a single request.

The cost is that each request has to carry everything it needs, which can make requests bigger.

How do logins work, then?

If the server forgets you after each request, how can it know that you're logged in? The client proves who it is on every request.

APIs usually do this by sending a token in a header:

GET /api/orders HTTP/1.1
Host: api.example.com
Authorization: Bearer dGVzdDp0ZXN0

Websites usually use cookies. The server asks the browser to store a value:

HTTP/1.1 200 OK
Set-Cookie: session=a1b2c3; HttpOnly; Secure

Then the browser sends that value back with each request:

GET /account HTTP/1.1
Host: www.example.com
Cookie: session=a1b2c3

Cookies let a website build sessions on top of HTTP. Each request still stands alone, because each one carries the cookie. But the server usually has to look up the session, so sessions bring back some of the costs of keeping state.

Connections are a separate idea

Connection: keep-alive lets a client send several requests over one network connection, which saves time. It doesn't make HTTP stateful, because each request is still understood on its own.

Discuss: A team designs this API for a two-step purchase. What goes wrong if there are two servers behind a load balancer? How would you redesign it?

POST /select-product with {"product": 42}, followed by POST /checkout

Summary

  • Each HTTP request carries everything needed to understand it.
  • Servers store resources, but don't remember conversations.
  • Clients send their credentials with every request.

Next, you'll put the whole chapter together, by fixing some broken requests.