← Better Programmer course
01
Beginner
2 hours 30 minutes

System Foundations

Follow a web request through the essential parts of a modern system.

Learning outcome

Explain how a browser finds a service, exchanges secure HTTP messages, reaches application code, and receives a response.

Jump to a chapter
  1. 1. Client, Server, Request, and Response
  2. 2. DNS: Names to Addresses
  3. 3. HTTP and HTTPS with TLS
  4. 4. Application Servers and APIs
  5. 5. State and Statelessness
  6. 6. Trace One Request End to End
  7. Applied exercise
  8. Knowledge check

Chapter 1

Client, Server, Request, and Response

Start with the smallest useful model of communication on the web.

A client is a program that asks for a service, while a server is a program that waits for requests and provides that service. A browser can be a client, but so can a mobile app or a command-line tool. The words describe roles in one interaction, not fixed kinds of machines. One program may be a server to a browser and a client when it calls another service.

This separation exists so users do not need to store every application's data and rules on their own devices. Step by step, the client opens a network connection, sends a request containing what it wants, and waits. The server reads the request, runs the relevant logic, and returns a response. The response carries a result or an error, after which the connection may close or be reused.

For example, a weather app requests the forecast for a city. Its request identifies the city and the desired operation. The server looks up forecast data and responds with structured values that the app renders. In practice, developers should identify the client and server at every boundary, record enough request context to diagnose failures, and design both success and error responses deliberately.

Key insight

Client and server are temporary roles connected by a request-response contract.

How to apply this

  • Draw the client, server, request, and response before discussing implementation details.
  • Define what a successful response and each expected failure look like.
  • Use a request identifier to connect client errors with server logs.
Scenario — A save button appears to do nothing

Situation

A note-taking app shows a spinner after Save, but the note never appears on another device.

Decision

Inspect the browser's outgoing request and incoming response first. This separates a client rendering problem from a server processing problem.

Chapter 2

DNS: Names to Addresses

Learn how a readable service name becomes a network destination.

The Domain Name System, or DNS, maps names such as api.example.com to network addresses. People and applications can keep using a stable name even when the server address changes. DNS exists because remembering addresses is inconvenient and tying a product directly to one machine makes migration and recovery difficult.

A lookup usually happens in stages. The client checks its local cache, then asks a recursive resolver, often operated by a network provider. If the resolver has no cached answer, it follows referrals through DNS authorities until it reaches the records for the domain. It returns the answer with a time to live, or TTL, which says how long the answer may be cached.

Suppose api.example.com has an A record pointing to 203.0.113.10. A browser resolves the name, caches the answer for its TTL, and then connects to that address. Practically, teams should lower TTL before a planned migration, verify records from more than one resolver, and remember that cached old answers make DNS changes gradual rather than immediate.

Key insight

DNS provides a cached layer of indirection between a service name and its current address.

How to apply this

  • Check name resolution separately from application health when a service is unreachable.
  • Plan for the TTL delay when changing production records.
  • Use service names rather than hard-coded addresses in application configuration.
Scenario — Traffic reaches an old server after migration

Situation

Most customers reach the new deployment, but a small group still reaches the previous address.

Decision

Compare DNS answers and their remaining TTLs. Keep the old endpoint safe until legitimate caches expire.

Chapter 3

HTTP and HTTPS with TLS

Understand the message format and the secure channel that carries it.

HTTP is an application protocol for requests and responses. A request has a method, target, headers, and sometimes a body; a response has a status code, headers, and sometimes a body. The protocol gives independent clients and servers a shared vocabulary. For example, GET asks to read a resource, while a 404 response says the requested resource was not found.

HTTPS is HTTP sent through Transport Layer Security, or TLS. First, the client connects and starts a TLS handshake. The server presents a certificate that links its public key to the requested name. The client validates the certificate, both sides agree on temporary session keys, and subsequent HTTP bytes are encrypted and protected against modification. TLS secures transport; it does not decide whether an authenticated user may access a record.

A browser might send GET /orders/42 with an Accept header and receive 200 plus JSON. Without TLS, another party on the network could read or alter that exchange. In practice, use HTTPS everywhere, avoid putting secrets in URLs where logs may capture them, select accurate status codes, and still perform authentication and authorization inside the application.

Key insight

HTTP defines the conversation; TLS makes that conversation private and tamper-resistant in transit.

How to apply this

  • Inspect method, target, status, headers, and body when debugging an HTTP exchange.
  • Automate certificate renewal and alert well before expiration.
  • Treat TLS and application access control as separate security requirements.
Scenario — A valid API call fails after certificate renewal

Situation

Clients report certificate errors even though the application process is healthy.

Decision

Inspect the certificate name, validity dates, and chain served by the endpoint before changing application code.

Chapter 4

Application Servers and APIs

See how an HTTP message is turned into application behavior.

An application server is a running program that receives requests and executes product rules. An API is the contract through which another program asks it to do work. The contract names operations, inputs, outputs, and errors. This boundary exists so callers can use a capability without knowing the server's internal classes, database layout, or programming language.

When a request arrives, a router matches its method and path to a handler. Middleware may authenticate the caller, parse input, and attach shared context. The handler validates business input, calls domain or storage code, and maps the result into an API response. A final error layer converts known failures into stable error shapes and logs unexpected failures for investigation.

For example, POST /tasks may accept a title. The server authenticates the user, rejects an empty title, stores a new task, and returns 201 with the created task. Practical API design means documenting the contract, validating at the boundary, keeping handlers focused, and changing responses compatibly because clients may deploy on a different schedule.

Key insight

An API is a stable external contract; the application server is one implementation of it.

How to apply this

  • Validate untrusted input before it reaches business or storage code.
  • Keep response and error shapes consistent across endpoints.
  • Add compatible fields rather than silently changing the meaning of existing fields.
Scenario — A mobile release breaks after an API change

Situation

The server renamed a response field, but many users still run last month's mobile app.

Decision

Restore the old field and introduce changes compatibly or behind an explicit API version.

Chapter 5

State and Statelessness

Separate durable facts from request processing that can happen anywhere.

State is information remembered across interactions, such as an account balance, shopping cart, or login session. A stateless request handler does not depend on private memory left by an earlier request. State is necessary for useful products, while stateless handlers are valuable because any equivalent server instance can process the next request.

In a stateless design, each request carries the identity and context needed to process it, and shared or durable state lives in an external store. A load balancer can therefore send consecutive requests to different instances. If a process stops, another instance reads the same durable facts and continues. Stateless does not mean the whole system has no state; it means request-serving processes do not own irreplaceable conversational state.

For example, an API instance validates a signed session token and loads a cart from a shared database. A second instance can handle checkout without seeing the first process's memory. In practice, locate each important piece of state, choose its owner and lifetime, avoid relying on local memory for correctness, and make temporary caches safe to lose.

Key insight

Stateless compute moves essential memory into explicit shared or durable systems.

How to apply this

  • List where user, session, workflow, and cached state live.
  • Test that a request succeeds after the serving process is replaced.
  • Treat local process memory as an optimization unless requests are deliberately pinned.
Scenario — Users are logged out on every second request

Situation

Two server instances keep sessions only in local memory while traffic alternates between them.

Decision

Move session state to a shared store or use verifiable tokens rather than depending on instance-local memory.

Chapter 6

Trace One Request End to End

Combine the foundations by following evidence across every boundary.

End-to-end tracing follows one request from the client through each component and back. It exists because a user sees one action while the system performs many steps. Looking at only one server can miss delays in name resolution, connection setup, downstream APIs, storage, or the client itself. A shared request or trace identifier ties evidence together.

Begin when the user acts and note the exact time. Follow DNS resolution, connection establishment, the TLS handshake, and the outgoing HTTP request. At the edge and application server, find logs with the same identifier, then inspect downstream calls and storage work. Finally, match the response status and timing to what the client received and rendered. Record duration at each boundary instead of guessing.

Imagine checkout takes four seconds. The browser timing shows a fast connection but a long wait for response bytes. The application trace shows most time inside a payment API call, while database work is quick. The practical action is to address that dependency with an appropriate timeout or product flow, not to optimize unrelated queries. Trace representative failures while protecting secrets and personal data in logs.

Key insight

A request identifier and boundary timings turn a distributed mystery into an ordered chain of evidence.

How to apply this

  • Propagate one trace identifier through internal calls and logs.
  • Measure time at every boundary before choosing an optimization.
  • Redact credentials and sensitive user data from diagnostic records.
Scenario — Checkout is slow only for some orders

Situation

Overall server utilization is normal, but orders using one payment method take several seconds.

Decision

Compare end-to-end traces by payment method and use their spans to isolate the slow dependency.

Applied exercise

Trace a page request on paper and in developer tools

Choose one public HTTPS page and build an evidence-based map from its name to the rendered response.

  1. 01Use browser developer tools to capture the main document request, status, request headers, response headers, and timing phases.
  2. 02Resolve the host name with a DNS tool and record the returned address and TTL.
  3. 03Draw the client, DNS resolver, edge or server, and any application boundary you can infer without claiming unseen details.
  4. 04Mark where TLS starts, where HTTP is processed, and which observable facts are stateful.
  5. 05Write one plausible failure at each boundary and the exact evidence you would inspect to confirm it.

Deliverable

A one-page request map with captured evidence, boundary timings, and a short diagnostic checklist.

Knowledge check

Check your understanding before finishing

Answer from the reasoning and trade-offs, not keyword memory. After submitting, review the explanation for every question.

Q1Why are client and server best understood as roles?
Q2What does a DNS TTL control?
Q3Which responsibility belongs to TLS rather than application authorization?
Q4What makes an application instance stateless?
Q5What is the strongest first step when one request is unexpectedly slow?