Nền tảng Internet & WebInternet & Web Fundamentals
Thuộc bộ kiến thức Backend Roadmap.
Tổng quan
Mọi backend bạn xây dựng đều nằm ở cuối một chuỗi dài gồm các network, protocol và máy chủ. Người dùng gõ một URL hoặc app gọi một API, và chỉ trong vài trăm mili-giây, một packet rời khỏi thiết bị của họ, đi qua các router và cáp quang biển, được giải mã, được parse, được định tuyến tới process của bạn, rồi được trả lời. Nếu không hiểu chuỗi này, bạn sẽ chẩn đoán sai latency, cấu hình sai TLS, làm rò rỉ cookie, và bối rối vì DNS caching.
Note này xây dựng mô hình tư duy mà một backend developer thực sự cần:
- Cách internet vận chuyển byte (packet, IP, TCP/UDP, client-server).
- Cách tên miền trở thành địa chỉ (DNS, domain, các record).
- Nơi code của bạn thực sự chạy (các mô hình hosting).
- HTTP chuyên sâu — protocol bạn dùng cả ngày (method, status code, header, cookie).
- HTTPS / TLS — mã hóa thực sự đem lại điều gì và handshake diễn ra ra sao.
- Một browser (hay client bất kỳ) gửi gì, và toàn bộ vòng đời request từ đầu đến cuối.
Lý thuyết networking sâu hơn (các tầng OSI, routing protocol, subnetting, congestion control) nằm ở ../../network-engineer/README.md. Ở đây ta giữ ở độ cao mà một backend engineer làm việc hằng ngày, và liên kết chéo tới Web Servers, APIs và Web Security khi các chủ đề đi sâu hơn.
Kiến thức nền tảng
Internet hoạt động thế nào
Internet là một “network của các network”, cùng thống nhất một cách chung để đánh địa chỉ và chuyển tiếp dữ liệu. Các ý tưởng cốt lõi:
- Packet. Dữ liệu không được gửi thành một luồng liên tục trên đường truyền. Nó bị cắt thành các packet nhỏ (thường tối đa ~1500 byte, là MTU của Ethernet). Mỗi packet mang một header (nguồn, đích, thông tin thứ tự) và một mẩu payload. Các packet đi độc lập và có thể theo những đường khác nhau.
- IP (Internet Protocol). IP là tầng đánh địa chỉ và định tuyến. Mọi thiết bị có thể tiếp cận trên network đều có một IP address: IPv4 (
93.184.216.34, 32-bit, ~4,3 tỉ địa chỉ, gần cạn) hoặc IPv6 (2606:2800:220:1:248:1893:25c8:1946, 128-bit, gần như vô hạn). Router chuyển tiếp packet từng chặng (hop) về phía IP đích. Bản thân IP là best-effort và không tin cậy — packet có thể bị mất, bị trùng, hoặc đến sai thứ tự. - Port. Một IP address xác định một máy; một port (0–65535) xác định một process/service cụ thể trên máy đó. HTTP mặc định port 80, HTTPS port 443, SSH port 22, PostgreSQL port 5432. Cặp
(IP, port)gọi là một socket. - TCP (Transmission Control Protocol). Xây trên IP để bổ sung tính tin cậy. TCP hướng kết nối (connection-oriented): nó thiết lập một session bằng three-way handshake (SYN → SYN-ACK → ACK), đánh số byte, truyền lại (retransmit) các segment bị mất, sắp xếp lại thứ tự, và áp dụng flow/congestion control. HTTP, HTTPS, SSH và các database protocol chạy trên TCP vì chúng cần mọi byte đến đúng thứ tự.
- UDP (User Datagram Protocol). Một tầng mỏng, không kết nối (connectionless) trên IP. Không handshake, không retransmission, không sắp thứ tự — chỉ “gửi và quên” các datagram. Latency và overhead thấp hơn, dùng cho DNS query, video/voice (WebRTC), game, và QUIC/HTTP3. Nếu packet bị mất, application tự quyết định có quan tâm hay không.
| Thuộc tính | TCP | UDP |
|---|---|---|
| Kết nối | Có (handshake) | Không |
| Giao nhận tin cậy | Có (retransmit) | Không |
| Thứ tự | Có | Không |
| Overhead | Cao hơn | Thấp hơn |
| Dùng điển hình | HTTP(S), SSH, DB | DNS, video, game, QUIC |
- Mô hình client-server. Hầu hết công việc backend theo mô hình này: một client (browser, mobile app, service khác) mở kết nối và gửi một request; một server (backend của bạn) lắng nghe trên một port, xử lý request, và gửi response. Server thụ động/lắng nghe; client là bên khởi tạo. (Khác với peer-to-peer, nơi mọi node vừa là client vừa là server.)
Ghép các tầng lại cho một API call bình thường: payload JSON của bạn được bọc bởi HTTP, chạy trên TLS (với HTTPS), chạy trên TCP, chạy trên IP, được mang bởi tầng physical/link (Ethernet, Wi-Fi, cáp quang). Mỗi tầng chỉ quan tâm header của chính nó và coi tầng trên là payload không cần hiểu.
DNS và tên miền
Con người dùng tên (api.example.com); network định tuyến bằng IP address. DNS (Domain Name System) là cơ sở dữ liệu phân tán, phân cấp, dùng để dịch tên thành địa chỉ (và nhiều hơn thế).
Tên miền (domain name) là gì. Domain name là một nhãn dễ đọc, được đăng ký trong không gian tên DNS toàn cầu, đọc từ phải qua trái theo các cấp:
api.example.com.
│ │ │ └── root (dấu chấm cuối, thường ngầm định)
│ │ └───── TLD (top-level domain): com, org, io, dev...
│ └───────────── SLD (second-level domain): example — phần bạn đăng ký/sở hữu
└───────────────── subdomain / hostname: api
Bạn thuê một domain từ một registrar (Namecheap, Cloudflare, Google Domains). Registrar ghi nhận các authoritative nameserver của bạn với registry của TLD. Các nameserver này lưu các DNS record của bạn.
Luồng resolution (phân giải). Khi một client cần IP của www.example.com:
- App hỏi stub resolver của OS, resolver này hỏi một recursive resolver (của ISP, hoặc
1.1.1.1/8.8.8.8). - Nếu chưa có trong cache, resolver hỏi một root nameserver: “ai quản lý
.com?” → nhận về các TLD nameserver của.com. - Resolver hỏi một TLD server của
.com: “ai là authoritative choexample.com?” → nhận về các authoritative nameserver củaexample.com. - Resolver hỏi authoritative server để lấy A record của
www.example.com→ nhận93.184.216.34. - Resolver cache câu trả lời theo TTL của record và trả về cho client.
Đây là lý do thay đổi DNS không tức thời: cache ở mọi cấp tuân theo TTL của record. TTL thấp thì lan truyền nhanh hơn nhưng tăng tải query.
Các loại record thường gặp.
| Record | Mục đích | Ví dụ giá trị |
|---|---|---|
A | Hostname → IPv4 | 93.184.216.34 |
AAAA | Hostname → IPv6 | 2606:2800:220:1::1946 |
CNAME | Alias tới một tên khác | example.com. |
MX | Mail server (kèm priority) | 10 mail.example.com. |
TXT | Text tùy ý (SPF, xác minh domain, DKIM) | "v=spf1 include:_spf.google.com ~all" |
NS | Ủy quyền một zone cho nameserver | ns1.cloudflare.com. |
SOA | Metadata của zone (serial, TTL) | — |
SRV | Vị trí service (host + port) | 10 5 5060 sip.example.com. |
CAA | CA nào được phép cấp cert | 0 issue "letsencrypt.org" |
Kiểm tra DNS bằng dig:
# A record và kết quả phân giải
$ dig www.example.com A +noall +answer
www.example.com. 86400 IN A 93.184.216.34
# Xem từng bước các authoritative server được dùng
$ dig +trace example.com
# Query một loại record cụ thể với một resolver cụ thể
$ dig @1.1.1.1 example.com MX +short
Hosting
Hosting đơn giản là có một máy luôn bật, có thể tiếp cận qua một public IP, đang chạy process backend của bạn. Các mô hình đánh đổi giữa mức độ kiểm soát và gánh nặng vận hành:
| Mô hình | Bạn nhận được | Bạn quản lý | Phù hợp cho |
|---|---|---|---|
| Shared hosting | Một phần của một server dùng chung nhiều tenant | Gần như không gì | Site nhỏ, rẻ |
| VPS | Một virtual machine với tài nguyên riêng | OS, runtime, deploy, vá lỗi | Kiểm soát đầy đủ, quy mô vừa |
| Dedicated server | Nguyên một máy vật lý | Mọi thứ (kể cả giới hạn phần cứng) | Hiệu năng/cô lập tối đa |
| Cloud (IaaS/PaaS) | VM theo yêu cầu, DB managed, load balancer, autoscaling | Tùy (ít hơn với PaaS) | Co giãn linh hoạt, đa số team |
| Serverless (FaaS) | Chạy function theo từng request; không phải quản server | Chỉ code của bạn | Workload dồn cục/hướng sự kiện |
Xu hướng là đi lên nấc thang trừu tượng: từ thuê phần cứng đến thuê năng lực. Serverless (AWS Lambda, Cloud Functions) loại bỏ hoàn toàn việc quản server và scale về 0, đổi lại có cold start và giới hạn thời gian chạy. Container + orchestration (Docker + Kubernetes) nằm ở giữa. Xem Web Servers để hiểu process thực sự nhận kết nối trên host.
Khái niệm chính
HTTP là gì
HTTP (HyperText Transfer Protocol) là protocol tầng application, dạng text, theo mô hình request-response, mà client và server dùng để trao đổi message. Các đặc tính chính:
- Stateless (phi trạng thái). Mỗi request độc lập; server không nhớ các request trước trừ khi bạn thêm state (cookie, session, token). Chính điều này khiến việc scale ngang trở nên dễ dàng.
- Client khởi tạo. Client luôn gửi request; server trả lời. (Server chủ động đẩy dữ liệu cần WebSockets hoặc SSE.)
- Các phiên bản. HTTP/1.1 (text, mỗi lúc một request trên một connection, keep-alive), HTTP/2 (binary, multiplex nhiều stream trên một TCP connection, nén header), HTTP/3 (chạy trên QUIC/UDP, loại bỏ head-of-line blocking của TCP).
Cấu trúc request:
GET /api/users/42 HTTP/1.1 ← method, path, version (request line)
Host: api.example.com ← các header
Accept: application/json
Authorization: Bearer eyJhbGci...
← dòng trống ngăn cách header với body
Cấu trúc response:
HTTP/1.1 200 OK ← version, status code, reason (status line)
Content-Type: application/json ← các header
Content-Length: 51
Cache-Control: no-store
{"id":42,"name":"Ada","role":"admin"} ← body
HTTP method
Method là động từ — thể hiện ý định của request.
| Method | Mục đích | Safe | Idempotent | Có body |
|---|---|---|---|---|
GET | Đọc một resource | Có | Có | Không |
HEAD | Như GET nhưng chỉ header | Có | Có | Không |
POST | Tạo mới / kích hoạt hành động | Không | Không | Có |
PUT | Thay thế toàn bộ resource | Không | Có | Có |
PATCH | Cập nhật một phần resource | Không | Không | Có |
DELETE | Xóa một resource | Không | Có | Không |
OPTIONS | Hỏi những gì được phép (CORS preflight) | Có | Có | Không |
- Safe = không thay đổi state phía server (chỉ đọc).
- Idempotent = gửi cùng một request N lần cho cùng kết quả như gửi một lần.
PUT/DELETEidempotent;POSTthì không (nên submit form hai lần có thể tạo hai bản ghi). Idempotency quan trọng cho việc retry an toàn — xem APIs.
HTTP status code
Mã ba chữ số, nhóm theo chữ số đầu:
| Dải | Nhóm | Ví dụ thường gặp |
|---|---|---|
1xx | Informational | 100 Continue, 101 Switching Protocols |
2xx | Success | 200 OK, 201 Created, 204 No Content |
3xx | Redirection | 301 Moved Permanently, 302 Found, 304 Not Modified |
4xx | Client error | 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict, 422 Unprocessable Entity, 429 Too Many Requests |
5xx | Server error | 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable, 504 Gateway Timeout |
Lưu ý cho backend: 401 nghĩa là “chưa xác thực” (không có/sai credentials); 403 nghĩa là “đã xác thực nhưng không được phép”. Trả 201 kèm header Location khi tạo mới. Dùng 429 kèm header Retry-After cho rate limiting. Đừng bao giờ trả 200 kèm payload lỗi — client và proxy dựa vào status code.
HTTP header
Header là metadata dạng Name: Value. Các nhóm bạn sẽ dùng liên tục:
| Header | Chiều | Mục đích |
|---|---|---|
Host | Request | Virtual host nào (bắt buộc trong HTTP/1.1) |
Content-Type | Cả hai | Media type của body (application/json, text/html) |
Content-Length | Cả hai | Kích thước body tính bằng byte |
Accept | Request | Media type client xử lý được |
Authorization | Request | Credentials (Bearer <token>, Basic ...) |
User-Agent | Request | Danh tính phần mềm client |
Cache-Control | Cả hai | Quy tắc cache (no-store, max-age=3600) |
ETag / If-None-Match | Cả hai | Request có điều kiện / kiểm tra cache |
Location | Response | Đích redirect hoặc URL resource vừa tạo |
Set-Cookie / Cookie | Resp / Req | Trao đổi cookie |
Access-Control-Allow-Origin | Response | Chính sách CORS |
X-Forwarded-For | Request | IP client gốc phía sau proxy/LB |
Cookie và state
HTTP là stateless, nên cookie dùng để mang state qua nhiều request. Server gửi Set-Cookie; browser lưu lại và gửi kèm ở các request sau tới domain đó qua header Cookie.
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax; Max-Age=3600; Path=/
Các thuộc tính quan trọng về bảo mật (chi tiết ở Web Security):
HttpOnly— JavaScript không truy cập được, giảm thiểu việc đánh cắp token qua XSS.Secure— chỉ gửi qua HTTPS.SameSite(Strict/Lax/None) — kiểm soát việc gửi cross-site, là phòng thủ CSRF chính.Domain/Path— giới hạn phạm vi cookie.Max-Age/Expires— thời gian sống; không có thì là session cookie.
Giải pháp stateless thay thế (JWT trong Authorization) tránh việc lưu session phía server nhưng khó thu hồi (revoke) hơn.
HTTPS, SSL/TLS
HTTPS là HTTP chạy bên trong một kênh mã hóa TLS (Transport Layer Security) (SSL là tiền thân đã lỗi thời của TLS — hãy dùng TLS 1.2/1.3). TLS đảm bảo ba điều:
- Confidentiality (bảo mật) — traffic được mã hóa; kẻ nghe lén chỉ thấy ciphertext.
- Integrity (toàn vẹn) — mọi sửa đổi bị phát hiện qua message authentication code.
- Authentication (xác thực) — server chứng minh danh tính bằng một certificate được ký bởi một Certificate Authority (CA) đáng tin, nên bạn biết mình đang nói chuyện với
example.comthật.
TLS 1.3 handshake (đơn giản hóa):
- ClientHello — client gửi phiên bản TLS hỗ trợ, các cipher suite, và một key-share (public key ephemeral).
- ServerHello — server chọn cipher, gửi key-share của nó và certificate (chứa public key, domain, và chữ ký của CA).
- Xác minh — client kiểm tra chuỗi certificate lên tới một root CA đáng tin, kiểm domain, hạn dùng, và trạng thái thu hồi.
- Sinh khóa — cả hai bên cùng suy ra một symmetric session key giống nhau từ các key-share đã trao đổi (ECDHE), đem lại forward secrecy.
- Dữ liệu application được mã hóa truyền bằng cipher đối xứng nhanh (ví dụ AES-GCM).
TLS 1.3 hoàn tất trong một round trip (1-RTT), có thể resume 0-RTT. TLS 1.2 cần hai. Certificate thường được cấp miễn phí bởi Let’s Encrypt (90 ngày, tự động gia hạn) hoặc bởi các CA thương mại. Việc terminate TLS thường diễn ra ở load balancer hoặc reverse proxy — xem Web Servers.
Browser và client (từ góc nhìn backend)
Từ góc nhìn backend, một browser chỉ là một HTTP client — nhưng là loại giàu tính năng. Nó gửi gì và làm gì:
- Parse URL, resolve DNS, mở kết nối TCP+TLS, và gửi một HTTP request kèm các header như
User-Agent,Accept,Accept-Language,Accept-Encoding, và mọiCookieđã lưu. - Thực thi same-origin policy và tôn trọng các header CORS của bạn với request cross-origin, gửi một preflight
OPTIONScho các request không “simple”. - Đi theo các redirect
3xx, tôn trọngCache-Control/ETagđể cache, và tự động giải nén responsegzip/br. - Render response HTML, rồi phát hàng loạt request tiếp theo cho CSS, JS, hình ảnh, và các lời gọi API/XHR/
fetch— nên một “lần tải trang” là hàng chục request tới backend của bạn.
Các client không phải browser (mobile app, curl, service khác) cũng nói HTTP nhưng bỏ qua render, cookie mặc định, và CORS. Backend của bạn không nên giả định là browser.
Vòng đời request từ đầu đến cuối
Điều thực sự diễn ra khi một client gọi https://api.example.com/users/42:
- Parse URL — scheme (
https), host (api.example.com), port (443 ngầm định), path, query. - DNS resolution — hostname → IP (cache → recursive resolver → root → TLD → authoritative), như trên.
- TCP handshake — SYN / SYN-ACK / ACK tới IP trên port 443.
- TLS handshake — thương lượng cipher, xác minh certificate, sinh session key.
- Gửi HTTP request — request line + header + body tùy chọn, qua kênh đã mã hóa.
- Đường đi trên network — packet đi qua các router/CDN edge về phía server.
- Xử lý phía server — một reverse proxy / load balancer có thể terminate TLS và định tuyến tới một backend instance; web server (xem Web Servers) chuyển request cho application của bạn, application chạy middleware (auth, logging), route tới handler, query database/cache, và dựng response.
- Trả HTTP response — status line + header + body đi ngược lại trên cùng kết nối.
- Client xử lý — parse status/header, giải nén, đi theo redirect, áp dụng cache, và (với browser) render hoặc (với API client) deserialize JSON.
- Tái sử dụng hoặc đóng kết nối — keep-alive/multiplexing của HTTP2 tái dùng kết nối cho các request sau; nếu không thì đóng.
Bạn có thể quan sát phần lớn quá trình này bằng curl -v:
$ curl -v https://api.example.com/users/42
* Trying 93.184.216.34:443...
* Connected to api.example.com (93.184.216.34) port 443
* TLS 1.3 handshake, cipher TLS_AES_256_GCM_SHA384
* Server certificate: CN=api.example.com; issuer: Let's Encrypt
> GET /users/42 HTTP/2 ← các header request ta gửi
> Host: api.example.com
> user-agent: curl/8.4.0
> accept: */*
>
< HTTP/2 200 ← các header response ta nhận
< content-type: application/json
< cache-control: no-store
<
{"id":42,"name":"Ada"}
Best Practices
- Luôn dùng HTTPS — TLS 1.2+ ở mọi nơi, redirect HTTP→HTTPS, bật HSTS, và tự động gia hạn certificate (Let’s Encrypt/ACME). Đừng bao giờ gửi credentials hay cookie qua HTTP thường.
- Chọn đúng method và status code. Các thao tác idempotent (
PUT,DELETE) cho phép retry an toàn; trả201+Locationkhi tạo mới,4xxcho lỗi client,5xxcho lỗi server — đừng bao giờ trả200kèm body lỗi. - Làm cứng cookie — đặt
HttpOnly,Secure, vàSameSitephù hợp cho mọi session cookie; giới hạn bằngDomain/Path; giữ thời gian sống ngắn. - Cấu hình cache có chủ đích — dùng
Cache-ControlvàETagđể client/CDN cache an toàn; dùngno-storecho response nhạy cảm. Cache đúng là một trong những cách giảm latency lớn nhất. - Chú ý TTL của DNS — hạ TTL trước một đợt migration đã lên kế hoạch để thay đổi lan truyền nhanh; nâng lại sau đó để giảm tải query.
- Tin proxy header một cách cẩn trọng — chỉ đọc IP client thật từ
X-Forwarded-Forkhi nó đến từ proxy bạn kiểm soát, nếu không bạn mở đường cho IP spoofing. - Cấu hình CORS tường minh — chỉ cho phép các origin, method, header bạn thực sự muốn; tránh
Access-Control-Allow-Origin: *cho các endpoint cần xác thực. Xem Web Security. - Ưu tiên HTTP/2 hoặc HTTP/3 ở edge để multiplex và nén header, đặc biệt với các client “nói nhiều”.
- Thiết kế backend stateless — giữ session state trong cookie/token hoặc một store dùng chung, không giữ trong bộ nhớ process, để bất kỳ instance nào cũng phục vụ được bất kỳ request nào và bạn có thể scale ngang.
- Đặt timeout và retry kèm backoff cho các lời gọi ra ngoài; một dependency treo cần fail nhanh, không làm cạn connection pool.
Tài liệu tham khảo
Part of the Backend Roadmap knowledge base.
Overview
Every backend you build lives at the far end of a long chain of networks, protocols, and machines. A user types a URL or an app fires an API call, and within a few hundred milliseconds a packet leaves their device, crosses routers and undersea cables, is decrypted, parsed, routed to your process, and answered. If you do not understand that chain, you will misdiagnose latency, misconfigure TLS, leak cookies, and be surprised by DNS caching.
This note builds the mental model a backend developer actually needs:
- How the internet moves bytes (packets, IP, TCP/UDP, client-server).
- How names become addresses (DNS, domains, records).
- Where your code physically runs (hosting models).
- HTTP in depth — the protocol you speak all day (methods, status codes, headers, cookies).
- HTTPS / TLS — what encryption actually buys you and how the handshake works.
- What a browser (or any client) sends, and the full request lifecycle end to end.
Deeper networking theory (OSI layers, routing protocols, subnetting, congestion control) lives in ../../network-engineer/README.md. Here we stay at the altitude a backend engineer works at day to day, and cross-link to Web Servers, APIs, and Web Security where the topics deepen.
Fundamentals
How the internet works
The internet is a network of networks that agree on a common way to address and forward data. The core ideas:
- Packets. Data is not sent as one continuous stream on the wire. It is chopped into small packets (typically up to ~1500 bytes, the Ethernet MTU). Each packet carries a header (source, destination, sequence info) and a chunk of payload. Packets travel independently and may take different routes.
- IP (Internet Protocol). IP is the addressing and routing layer. Every device reachable on a network has an IP address: IPv4 (
93.184.216.34, 32-bit, ~4.3 billion addresses, mostly exhausted) or IPv6 (2606:2800:220:1:248:1893:25c8:1946, 128-bit, effectively unlimited). Routers forward packets hop by hop toward the destination IP. IP itself is best-effort and unreliable — packets can be dropped, duplicated, or arrive out of order. - Ports. An IP address identifies a machine; a port (0–65535) identifies a specific process/service on it. HTTP defaults to port 80, HTTPS to 443, SSH to 22, PostgreSQL to 5432. The pair
(IP, port)is a socket. - TCP (Transmission Control Protocol). Built on top of IP to add reliability. TCP is connection-oriented: it establishes a session with a three-way handshake (SYN → SYN-ACK → ACK), numbers bytes, retransmits lost segments, reorders them, and applies flow/congestion control. HTTP, HTTPS, SSH, and database protocols run over TCP because they need every byte in order.
- UDP (User Datagram Protocol). A thin, connectionless layer over IP. No handshake, no retransmission, no ordering — just “fire and forget” datagrams. Lower latency and overhead, used by DNS queries, video/voice (WebRTC), gaming, and QUIC/HTTP3. If a packet is lost, the application decides whether to care.
| Property | TCP | UDP |
|---|---|---|
| Connection | Yes (handshake) | No |
| Reliable delivery | Yes (retransmits) | No |
| Ordering | Yes | No |
| Overhead | Higher | Lower |
| Typical use | HTTP(S), SSH, DB | DNS, video, gaming, QUIC |
- Client-server model. Most backend work follows this pattern: a client (browser, mobile app, another service) opens a connection and sends a request; a server (your backend) listens on a port, processes the request, and sends a response. The server is passive/listening; the client initiates. (Contrast with peer-to-peer, where every node is both.)
Putting the layers together for a normal API call: your JSON payload is wrapped by HTTP, which rides on TLS (for HTTPS), which rides on TCP, which rides on IP, which is carried by the physical/link layer (Ethernet, Wi-Fi, fiber). Each layer only cares about its own header and treats the layer above as opaque payload.
DNS and domain names
Humans use names (api.example.com); the network routes on IP addresses. DNS (Domain Name System) is the distributed, hierarchical database that translates names to addresses (and more).
What a domain name is. A domain name is a human-readable label registered in the global DNS namespace, read right-to-left in levels:
api.example.com.
│ │ │ └── root (the trailing dot, usually implicit)
│ │ └───── TLD (top-level domain): com, org, io, dev...
│ └───────────── SLD (second-level domain): example — what you register/own
└───────────────── subdomain / hostname: api
You lease a domain from a registrar (Namecheap, Cloudflare, Google Domains). The registrar records your authoritative nameservers with the TLD registry. Those nameservers hold your DNS records.
Resolution flow. When a client needs the IP for www.example.com:
- The app asks the OS stub resolver, which asks a recursive resolver (your ISP’s, or
1.1.1.1/8.8.8.8). - If not cached, the resolver asks a root nameserver: “who handles
.com?” → gets the.comTLD nameservers. - Resolver asks a
.comTLD server: “who is authoritative forexample.com?” → getsexample.com’s authoritative nameservers. - Resolver asks the authoritative server for the
www.example.comA record → gets93.184.216.34. - The resolver caches the answer for its TTL and returns it to the client.
This is why DNS changes are not instant: caches at every level honor the record’s TTL. Lower TTLs propagate faster but increase query load.
Common record types.
| Record | Purpose | Example value |
|---|---|---|
A | Hostname → IPv4 | 93.184.216.34 |
AAAA | Hostname → IPv6 | 2606:2800:220:1::1946 |
CNAME | Alias to another name | example.com. |
MX | Mail servers (with priority) | 10 mail.example.com. |
TXT | Arbitrary text (SPF, domain verification, DKIM) | "v=spf1 include:_spf.google.com ~all" |
NS | Delegates a zone to nameservers | ns1.cloudflare.com. |
SOA | Zone metadata (serial, TTLs) | — |
SRV | Service location (host + port) | 10 5 5060 sip.example.com. |
CAA | Which CAs may issue certs | 0 issue "letsencrypt.org" |
Inspect DNS with dig:
# A record and the resolution path
$ dig www.example.com A +noall +answer
www.example.com. 86400 IN A 93.184.216.34
# See which authoritative servers are used, step by step
$ dig +trace example.com
# Query a specific record type against a specific resolver
$ dig @1.1.1.1 example.com MX +short
Hosting
Hosting is simply having a machine that is always on, reachable on a public IP, running your backend process. The models trade off control against operational burden:
| Model | What you get | You manage | Good for |
|---|---|---|---|
| Shared hosting | A slice of one server shared with many tenants | Almost nothing | Small sites, cheap |
| VPS | A virtual machine with dedicated resources | OS, runtime, deploys, patching | Full control, moderate scale |
| Dedicated server | A whole physical machine | Everything (incl. hardware limits) | Max performance/isolation |
| Cloud (IaaS/PaaS) | On-demand VMs, managed DBs, load balancers, autoscaling | Varies (less on PaaS) | Elastic scale, most teams |
| Serverless (FaaS) | Run functions per-request; no servers to manage | Just your code | Spiky/event-driven workloads |
The trend is up the abstraction ladder: from renting hardware to renting capabilities. Serverless (AWS Lambda, Cloud Functions) removes server management entirely and scales to zero, at the cost of cold starts and execution limits. Containers + orchestration (Docker + Kubernetes) sit in between. See Web Servers for the process that actually accepts connections on the host.
Key Concepts
What HTTP is
HTTP (HyperText Transfer Protocol) is the application-layer, text-based, request-response protocol that clients and servers use to exchange messages. Key properties:
- Stateless. Each request is independent; the server keeps no memory of previous requests unless you add state (cookies, sessions, tokens). This is what makes horizontal scaling easy.
- Client-initiated. The client always sends the request; the server responds. (Server push requires WebSockets or SSE.)
- Versions. HTTP/1.1 (text, one request per connection at a time, keep-alive), HTTP/2 (binary, multiplexed streams over one TCP connection, header compression), HTTP/3 (runs over QUIC/UDP, eliminates TCP head-of-line blocking).
Request structure:
GET /api/users/42 HTTP/1.1 ← method, path, version (request line)
Host: api.example.com ← headers
Accept: application/json
Authorization: Bearer eyJhbGci...
← blank line separates headers from body
Response structure:
HTTP/1.1 200 OK ← version, status code, reason (status line)
Content-Type: application/json ← headers
Content-Length: 51
Cache-Control: no-store
{"id":42,"name":"Ada","role":"admin"} ← body
HTTP methods
The method is the verb — the intent of the request.
| Method | Purpose | Safe | Idempotent | Body |
|---|---|---|---|---|
GET | Read a resource | Yes | Yes | No |
HEAD | Like GET, headers only | Yes | Yes | No |
POST | Create / trigger an action | No | No | Yes |
PUT | Replace a resource entirely | No | Yes | Yes |
PATCH | Partially update a resource | No | No | Yes |
DELETE | Remove a resource | No | Yes | No |
OPTIONS | Ask what’s allowed (CORS preflight) | Yes | Yes | No |
- Safe = no server-side state change (read-only).
- Idempotent = making the same request N times has the same effect as making it once.
PUT/DELETEare idempotent;POSTis not (which is why double-submitting a form can create two records). Idempotency matters for safe retries — see APIs.
HTTP status codes
Three-digit codes grouped by first digit:
| Range | Class | Common examples |
|---|---|---|
1xx | Informational | 100 Continue, 101 Switching Protocols |
2xx | Success | 200 OK, 201 Created, 204 No Content |
3xx | Redirection | 301 Moved Permanently, 302 Found, 304 Not Modified |
4xx | Client error | 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict, 422 Unprocessable Entity, 429 Too Many Requests |
5xx | Server error | 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable, 504 Gateway Timeout |
Backend tips: 401 means “not authenticated” (no/invalid credentials); 403 means “authenticated but not allowed”. Return 201 with a Location header on creation. Use 429 with a Retry-After header for rate limiting. Never return 200 with an error payload — clients and proxies rely on the code.
HTTP headers
Headers are Name: Value metadata. Categories you will use constantly:
| Header | Direction | Purpose |
|---|---|---|
Host | Request | Which virtual host (required in HTTP/1.1) |
Content-Type | Both | Media type of the body (application/json, text/html) |
Content-Length | Both | Body size in bytes |
Accept | Request | Media types the client can handle |
Authorization | Request | Credentials (Bearer <token>, Basic ...) |
User-Agent | Request | Client software identity |
Cache-Control | Both | Caching rules (no-store, max-age=3600) |
ETag / If-None-Match | Both | Conditional requests / cache validation |
Location | Response | Redirect target or created-resource URL |
Set-Cookie / Cookie | Resp / Req | Cookie exchange |
Access-Control-Allow-Origin | Response | CORS policy |
X-Forwarded-For | Request | Original client IP behind a proxy/LB |
Cookies and state
HTTP is stateless, so cookies carry state across requests. The server sends Set-Cookie; the browser stores it and returns it on subsequent requests to that domain via the Cookie header.
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax; Max-Age=3600; Path=/
Security-critical attributes (details in Web Security):
HttpOnly— inaccessible to JavaScript, mitigating XSS token theft.Secure— only sent over HTTPS.SameSite(Strict/Lax/None) — controls cross-site sending, the primary CSRF defense.Domain/Path— scope the cookie.Max-Age/Expires— lifetime; without them the cookie is a session cookie.
Stateless alternatives (JWTs in Authorization) avoid server-side session storage but can’t be revoked as easily.
HTTPS, SSL/TLS
HTTPS is HTTP running inside a TLS (Transport Layer Security) encrypted channel (SSL is TLS’s deprecated predecessor — use TLS 1.2/1.3). TLS provides three guarantees:
- Confidentiality — traffic is encrypted; eavesdroppers see only ciphertext.
- Integrity — tampering is detected via message authentication codes.
- Authentication — the server proves its identity via a certificate signed by a trusted Certificate Authority (CA), so you know you’re talking to the real
example.com.
The TLS 1.3 handshake (simplified):
- ClientHello — client sends supported TLS version, cipher suites, and a key-share (ephemeral public key).
- ServerHello — server picks the cipher, sends its key-share and its certificate (containing its public key and domain, signed by a CA).
- Verification — client validates the certificate chain up to a trusted root CA, checks the domain, expiry, and revocation.
- Key derivation — both sides derive the same symmetric session key from the exchanged key-shares (ECDHE), giving forward secrecy.
- Encrypted application data flows using the fast symmetric cipher (e.g. AES-GCM).
TLS 1.3 completes this in one round trip (1-RTT), with 0-RTT resumption possible. TLS 1.2 needed two. Certificates are commonly issued free by Let’s Encrypt (90-day, auto-renewed) or by commercial CAs. Termination often happens at a load balancer or reverse proxy — see Web Servers.
Browsers and clients (from the backend’s view)
From your backend’s perspective, a browser is just an HTTP client — but a feature-rich one. What it sends and does:
- Parses the URL, resolves DNS, opens a TCP+TLS connection, and sends an HTTP request with headers like
User-Agent,Accept,Accept-Language,Accept-Encoding, and any storedCookies. - Enforces the same-origin policy and honors your CORS headers on cross-origin requests, sending an
OPTIONSpreflight for non-simple requests. - Follows
3xxredirects, respectsCache-Control/ETagfor caching, and automatically decompressesgzip/brresponses. - Renders the HTML response, then issues many follow-up requests for CSS, JS, images, and API/XHR/
fetchcalls — so one “page load” is dozens of requests to your backend.
Non-browser clients (mobile apps, curl, other services) speak the same HTTP but skip rendering, cookies-by-default, and CORS. Your backend should not assume a browser.
The end-to-end request lifecycle
What actually happens when a client calls https://api.example.com/users/42:
- URL parse — scheme (
https), host (api.example.com), port (443 implied), path, query. - DNS resolution — hostname → IP (cache → recursive resolver → root → TLD → authoritative), as above.
- TCP handshake — SYN / SYN-ACK / ACK to the IP on port 443.
- TLS handshake — negotiate cipher, validate certificate, derive session key.
- HTTP request sent — request line + headers + optional body, over the encrypted channel.
- Network path — packets traverse routers/CDN edges toward the server.
- Server-side processing — a reverse proxy / load balancer may terminate TLS and route to a backend instance; the web server (see Web Servers) hands the request to your application, which runs middleware (auth, logging), routes to a handler, queries the database/cache, and builds a response.
- HTTP response returned — status line + headers + body travel back over the same connection.
- Client handles it — parses the status/headers, decompresses, follows redirects, applies caching, and (for a browser) renders or (for an API client) deserializes the JSON.
- Connection reuse or close — keep-alive/HTTP2 multiplexing reuses the connection for subsequent requests; otherwise it closes.
You can watch most of this with curl -v:
$ curl -v https://api.example.com/users/42
* Trying 93.184.216.34:443...
* Connected to api.example.com (93.184.216.34) port 443
* TLS 1.3 handshake, cipher TLS_AES_256_GCM_SHA384
* Server certificate: CN=api.example.com; issuer: Let's Encrypt
> GET /users/42 HTTP/2 ← request headers we send
> Host: api.example.com
> user-agent: curl/8.4.0
> accept: */*
>
< HTTP/2 200 ← response headers we get
< content-type: application/json
< cache-control: no-store
<
{"id":42,"name":"Ada"}
Best Practices
- Always use HTTPS — TLS 1.2+ everywhere, redirect HTTP→HTTPS, enable HSTS, and automate certificate renewal (Let’s Encrypt/ACME). Never send credentials or cookies over plain HTTP.
- Choose correct methods and status codes. Idempotent operations (
PUT,DELETE) enable safe retries; return201+Locationon create,4xxfor client faults,5xxfor server faults — never200with an error body. - Harden cookies — set
HttpOnly,Secure, and an appropriateSameSiteon every session cookie; scope withDomain/Path; keep lifetimes short. - Set caching deliberately — use
Cache-ControlandETagso clients/CDNs cache safely; useno-storefor sensitive responses. Correct caching is one of the biggest latency wins. - Mind DNS TTLs — lower TTLs before a planned migration so changes propagate quickly; raise them afterward to cut query load.
- Trust proxy headers carefully — read the real client IP from
X-Forwarded-Foronly when it comes from a proxy you control, or you enable IP spoofing. - Configure CORS explicitly — allow only the origins, methods, and headers you intend; avoid
Access-Control-Allow-Origin: *for authenticated endpoints. See Web Security. - Prefer HTTP/2 or HTTP/3 at the edge for multiplexing and header compression, especially for chatty clients.
- Design stateless backends — keep session state in cookies/tokens or a shared store, not in process memory, so any instance can serve any request and you can scale horizontally.
- Set timeouts and retries with backoff on outbound calls; a hung dependency should fail fast, not exhaust your connection pool.