Lesson 2
Clients, Servers & Requests
Learn how clients and servers communicate through HTTP requests and responses — the foundation of the web.
25 min read · Beginner
The conversation that powers the web
Every time you load a webpage, check your email, or post a message, two programs are having a structured conversation. One program — the client — asks for something. Another program — the server — listens, processes the request, and sends back a response. This pattern is so fundamental that most of the internet runs on it.
As a developer, understanding this request-response cycle is your entry point to system architecture. Before you worry about databases, caches, or load balancers, you need a clear mental model of how a single client talks to a single server. Everything else is an extension of this basic idea.
Client-server separation
The client and server are separate programs, often on separate machines, connected by a network:
The client never touches the database directly. All data flows through the server.
This separation is the foundation of web security and scalability. You can update the server without forcing users to reinstall an app. You can add more servers without changing the client at all.
Clients: the askers
A client is any program that initiates requests. When you type a URL into Chrome, the browser is the client. When your phone app fetches your feed, the app is the client. Even a server can act as a client when it calls another service — but the role is always the same: send a request and wait for a response.
Clients are responsible for presenting information to users and capturing their input. They should stay “thin” when possible — meaning they handle display and interaction, while the server handles business logic and data access.
Here is what a simple client request looks like in JavaScript:
const response = await fetch("https://archtutor.dev/api/lessons");
const lessons = await response.json();
console.log(lessons);Servers: the responders
A server is a program that waits for incoming requests, processes them, and returns responses. It runs continuously on a machine (physical or virtual) that has a known address on the network. Web servers like NGINX or application servers like Node.js, Python’s Gunicorn, or Java’s Tomcat all play this role.
Servers enforce rules: Is this user allowed to do this? Is the data valid? What should happen if something goes wrong? Keeping these rules on the server — rather than trusting the client — is a core security principle.
HTTP methods at a glance
HTTP methods tell the server what kind of action the client wants:
| Method | Purpose | Safe? | Idempotent? | Example |
|---|---|---|---|---|
| GET | Read data | Yes | Yes | Fetch a user profile |
| POST | Create new resource | No | No | Submit a form, create order |
| PUT | Replace entire resource | No | Yes | Update all fields of a profile |
| PATCH | Partial update | No | No | Change just the email field |
| DELETE | Remove resource | No | Yes | Delete a todo item |
| HEAD | Like GET but no body | Yes | Yes | Check if resource exists |
Safe means the request does not change server state. Idempotent means calling it multiple times has the same effect as calling it once. These properties matter for retries — if a network blip causes a duplicate PUT, you will not accidentally create two resources.
Request anatomy
Every HTTP request has three parts:
POST /api/todos HTTP/1.1 ← Request line (method, path, version)
Host: archtutor.dev ← Headers (metadata)
Content-Type: application/json
Authorization: Bearer eyJhbG... ← Auth token
{"title": "Learn architecture"} ← Body (optional payload)
Here is the same request and its response as raw text — exactly what travels over the wire:
POST /api/todos HTTP/1.1
Host: archtutor.dev
Content-Type: application/json
Authorization: Bearer eyJhbG...
{"title": "Learn architecture"}HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/todos/42
{"id": 42, "title": "Learn architecture", "done": false}Key headers to know:
| Header | Purpose |
|---|---|
Host | Which server to route to (required) |
Content-Type | Format of the body (application/json, text/html) |
Authorization | Credentials (Bearer token, API key) |
Accept | What response formats the client can handle |
Cookie | Session identifier stored by the browser |
Response anatomy
The server replies with a similar structure:
HTTP/1.1 201 Created ← Status line
Content-Type: application/json
Location: /api/todos/42
{"id": 42, "title": "Learn architecture", "done": false}
Status codes are grouped by meaning:
| Range | Meaning | Examples |
|---|---|---|
| 2xx | Success | 200 OK, 201 Created, 204 No Content |
| 3xx | Redirect | 301 Moved, 304 Not Modified |
| 4xx | Client error | 400 Bad Request, 401 Unauthorized, 404 Not Found |
| 5xx | Server error | 500 Internal Error, 503 Service Unavailable |
HTTPS and why it matters
HTTP sends everything in plain text. Anyone on the same Wi-Fi network can read passwords, tokens, and personal data. HTTPS wraps HTTP in TLS encryption — the “S” stands for Secure.
HTTP: Client ----[readable text]----> Server
HTTPS: Client ----[encrypted blob]----> Server
In practice:
- Always use HTTPS in production — browsers mark HTTP sites as “Not Secure”
- TLS also verifies server identity via certificates, preventing impersonation
- The TLS handshake adds a small latency cost (~1 round trip), but CDNs and HTTP/2 minimize this
Never send passwords or API keys over plain HTTP. Treat HTTP as acceptable only for local development.
Stateless vs stateful
Stateless servers do not remember previous requests. Each request carries all the context needed (usually via tokens or cookies). This is the default for REST APIs and makes horizontal scaling easy — any server can handle any request.
Stateful servers keep session data in memory. If Server A handled your login, only Server A knows you are authenticated. This requires sticky sessions or shared session storage when you scale to multiple servers.
| Approach | Pros | Cons |
|---|---|---|
| Stateless (JWT tokens) | Easy to scale, no server memory | Tokens harder to revoke instantly |
| Stateful (server sessions) | Easy to invalidate sessions | Needs sticky sessions or Redis |
Most modern apps use stateless APIs with JWT or session tokens stored in Redis for the best of both worlds.
The HTTP request lifecycle
HTTP (Hypertext Transfer Protocol) is the language clients and servers use to communicate on the web. Let’s walk through what happens when you visit a website:
HTTP Request Flow
DNS Lookup
The client resolves the domain name to an IP address.
archtutor.dev → DNS Server → 192.0.2.42
When you type archtutor.dev into your browser, it first asks a DNS (Domain Name System) server: what IP address belongs to this name? DNS is like a phone book for the internet. The answer might be something like 192.0.2.42 — the actual location of the server. DNS results are cached at multiple levels (browser, OS, ISP) to speed up repeat visits.
In practice
When debugging a slow page load, work through the lifecycle above. Is DNS slow? Is TLS taking too long? Is the server returning a 500? Tools like browser DevTools (Network tab) and curl -v show you exactly where time is spent.
Key takeaways
- Clients initiate requests; servers respond — this is the fundamental pattern of the web
- HTTP is the protocol that structures these conversations with methods, headers, and status codes
- Keep business logic on the server — clients can be modified by users and should not be trusted
- HTTPS encrypts traffic — always use it in production
- Stateless servers scale better — carry context in tokens, not server memory
- Every web interaction follows a request-response cycle, even when it feels instant
Common mistakes
- Assuming the client and server are always separate machines — during local development, both often run on your laptop, but the roles remain distinct
- Ignoring HTTP methods — using GET for actions that change data can cause bugs and security issues
- Not handling error status codes — a 500 error from the server means something broke; show a helpful message
- Sending sensitive data over HTTP — use HTTPS everywhere outside localhost
Go deeper
- MDN HTTP Overview — the definitive reference for how HTTP works
- How the Web Works (MDN) — beginner-friendly walkthrough
- HTTP Status Codes Reference — know what each code means