Client and server
Byte: Every tower in this city speaks one language: HTTP.
Your frontend is the client. It sends a request and waits. The backend is the server. It reads the request, does the work, and sends back a response.
When you call fetch("/api/signup"), this is what happens on the other end. The whole curriculum is about what the server does in between.
Quick check: Who starts an HTTP exchange?
- The client sends a request
- The server pushes a response first
The client always asks first; the server answers.
Anatomy of a request
Byte: Four parts. Learn them once, use them forever.
A request has a method (what to do), a path (which resource), headers (metadata such as content type or auth token) and an optional body (the data, usually JSON).
POST /signup HTTP/1.1 <- method + pathHost: backend.cityContent-Type: application/json <- headersAuthorization: Bearer eyJhbGci...{"username": "neo", "age": 25} <- body
Quick check: Which part carries the JSON data?
- The path
- The headers
- The body
The body carries the data. Headers describe it (for example Content-Type: application/json).
Methods say what to do
Byte: Same path, different method, different meaning.
The method tells the server the intent. GET /users/7 reads user 7; DELETE /users/7 removes it.
| Method | Means |
|---|---|
| GET | read data; never changes anything |
| POST | create something new |
| PUT | replace something completely |
| PATCH | change part of something |
| DELETE | remove something |
Quick check: A learner updates only their display name. Which method fits best?
- GET
- PATCH
- DELETE
PATCH changes part of a resource. PUT would replace the whole profile.
Status codes say what happened
Byte: Read the first digit and you know who to blame.
- 2xx Success
201 Created, 200 OK. The packet got in.
- 4xx Client's fault
422 invalid data, 404 not found. Bounced at the gate.
- 5xx Server's fault
500: your code crashed. The tower sparks.
Every response starts with a three-digit status code. These are the ones you'll meet most:
| Code | Means |
|---|---|
| 200 OK | it worked, here is the data |
| 201 Created | a new thing was created |
| 400 Bad Request | the request is malformed |
| 401 Unauthorized | you're not logged in |
| 403 Forbidden | logged in, but not allowed |
| 404 Not Found | that resource doesn't exist |
| 422 Unprocessable Content | valid JSON, but the data breaks the rules |
| 500 Internal Server Error | the server's code crashed |
Quick check: A visitor who isn't logged in opens their profile. Which status fits?
- 401
- 403
- 404
401 means we don't know who you are. 403 means we know, and the answer is still no.
Every request stands alone
Byte: The server forgets you the moment it answers.
HTTP is stateless: the server doesn't remember the previous request. Anything it needs, such as who you are, must come with each request, usually in a cookie or an Authorization header.
That's why the same backend can run on many machines at once. You'll use this in the Citadel (auth) and the Skyline (scaling).
Quick check: How does the server know who sent the second request after you log in?
- It remembers the first request
- A cookie or token is sent with every request
Identity travels with every request. The server keeps no memory of the conversation.