HTTP in 10 Minutes
Requests, responses, methods, and the journey of a click.
HTTP is the language browsers and servers speak. Every page, every API call, every image you've ever loaded came through HTTP. The beautiful part: it's just text. You can read it with your eyes. By the end of this lesson, you'll be able to look at a raw HTTP exchange and explain every line.
The request/response loop
HTTP is a request/response protocol. The client (your browser, an app, curl) sends a request. The server reads it, does its work, and sends back a response. That's the whole model. Each request is independent: HTTP itself has no concept of "you," which is why cookies and tokens exist.
Anatomy of a request
An HTTP request has three parts: a start line, headers, and an optional body.
POST /api/users HTTP/1.1
Host: example.com
User-Agent: curl/8.4.0
Accept: application/json
Content-Type: application/json
Content-Length: 38
Authorization: Bearer eyJhbGc...
{"name":"Ada","email":"ada@x.com"}Line by line: the method (POST), the path (/api/users), the protocol version. Then headers, one per line, key-colon-value. A blank line. Then the body - here some JSON.
Anatomy of a response
HTTP/1.1 201 Created
Content-Type: application/json
Content-Length: 52
Location: /api/users/42
Set-Cookie: session=abc123; HttpOnly; Secure
{"id":42,"name":"Ada","email":"ada@x.com"}Same shape: a status line (protocol + status code + reason), headers, blank line, body. The reason phrase ("Created") is for humans; the status number is what code reads.
The methods (verbs)
Methods describe intent. The server doesn't enforce them - that's on you - but conventions are strong.
- GET - fetch something. Safe (no side effects), idempotent (call it twice, same result), cacheable.
- POST - create something or trigger an action. Generally not idempotent. The catch-all when nothing else fits.
- PUT - replace a resource at a known URL. Idempotent (PUTting the same data twice yields the same state).
- PATCH- partial update. "Change just these fields." Not necessarily idempotent.
- DELETE- remove a resource. Idempotent (deleting something already gone is still "gone").
Status codes worth memorizing
Status codes are grouped by first digit. 2xx is success. 3xx is redirection. 4xxmeans "you (the client) screwed up." 5xx means "we (the server) screwed up."
- 200 OK - the default success. Body has what you asked for.
- 201 Created - POST succeeded and made a new thing. Usually paired with a
Locationheader. - 301 Moved Permanently - this URL has moved forever. Browsers and search engines update bookmarks/indexes.
- 302 Found - temporary redirect. Don't update bookmarks.
- 304 Not Modified - cached copy is still fresh. The server saves bandwidth by sending no body.
- 400 Bad Request - your request is malformed. Invalid JSON, missing required field, etc.
- 401 Unauthorized - you're not logged in (or your token is bad). Authenticate and retry.
- 403 Forbidden - you're logged in but not allowed. Don't retry; ask for access.
- 404 Not Found - that URL doesn't exist.
- 422 Unprocessable Entity - the request is well-formed but semantically wrong (validation failed).
- 429 Too Many Requests - slow down. Usually paired with a
Retry-Afterheader. - 500 Internal Server Error - something on the server blew up. Generic catch-all.
- 502 Bad Gateway - the server in front (e.g. nginx, a load balancer) couldn't talk to the server behind it.
- 503 Service Unavailable - the server is up but not accepting traffic. Maintenance, overload, or rate limiting.
Headers: the metadata layer
Headers carry everything that isn't the body: content type, caching rules, cookies, auth, CORS info. A few you'll see daily:
Content-Type- what kind of data the body is (application/json,text/html,image/png).Authorization- credentials. UsuallyBearer <token>these days.Cache-Control- how long this response may be cached and by whom.Set-Cookie/Cookie- server sets, browser sends back next time.User-Agent- what client is making the request. Lies abound.
See it for real with curl
curl -v prints the entire HTTP exchange. Try this in your terminal:
curl -v https://api.github.com/zen
# > GET /zen HTTP/2
# > Host: api.github.com
# > User-Agent: curl/8.4.0
# > Accept: */*
# >
# < HTTP/2 200
# < content-type: text/plain
# < cache-control: max-age=60
# <
# Mind your words, they are important.Lines starting with > are what curl sent. Lines with <are what came back. The body is at the bottom. That's every HTTP request you've ever made, demystified.
HTTP versions in 30 seconds
- HTTP/1.1 (1997) - text-based, one request per connection (mostly). Still everywhere.
- HTTP/2 (2015) - binary framing, multiple parallel requests on one connection. Faster page loads.
- HTTP/3 (2022) - built on QUIC (UDP). Better on patchy mobile networks.
The semantics are the same across versions. Methods, status codes, headers, body - all identical. Only the wire format changes.
Quick quiz
Which method should you use to fetch data without side effects?
Recap
- HTTP is request/response, text-based, and stateless.
- Requests have a method + path + headers + optional body. Responses have a status code + headers + body.
- Methods:
GET(read),POST(create/act),PUT(replace),PATCH(update),DELETE(remove). - Status codes: 2xx success, 3xx redirect, 4xx client error, 5xx server error.
- Use
curl -vto see real HTTP traffic. It's the fastest way to learn.