WEB / WEB-01.02
The end-to-end journey of a request
Follow each transition from URL to handler, book record to response and DOM. Separate a 404 response from a network failure.
What to follow on the first pass
Send a request and separate three moments: receiving the response, consuming its body and updating the screen.
First follow Browser → Application → Browser. A 200 or 404 is an HTTP outcome; consuming JSON and changing the DOM are later operations.
- Request / response
- The request sent by the browser and the peer’s response.
- Status / body
- Status expresses the HTTP outcome; the body carries the content.
- Parsing / DOM update
- Parsing reads received text as data. A DOM update writes that data into the page structure.
Where do the later details fit?
DNS address lookup, TCP/QUIC connections and TLS protection are developed in later modules. Recognize the names here; the first pass does not require mastering all of them.
1. Core · Mechanism
Read every scenario without motion
Record found
- The intent starts in the browser
The intent to open a book has not reached the server. Other actors do not know this request.
- Browser
- Card pending
- Application
- No request
- Local data source
- No query
- The HTTP request arrived
The method and resource selection reached the application. No record has been read yet.
- Browser
- Waiting for response
- Application
- GET /api/book received
- Local data source
- No query
- The handler runs locally
The application selects a route, interprets input and prepares a read. This stage is not another network message.
- Browser
- Waiting for response
- Application
- Handler → readBook
- Local data source
- No query
- The read reached persistence
Data access in this example is a local call in the same process. The separate card shows logical responsibility, not another database host or network packet.
- Browser
- Waiting for response
- Application
- Waiting for read result
- Local data source
- readBook request received
- The data layer determines a result
The Atlas Notları record was found. A row existing does not mean the browser has learned anything.
- Browser
- Waiting for response
- Application
- Waiting for read result
- Local data source
- Result: Atlas Notları
- The read result is in the application
The application received the result; serialization and HTTP status selection are its responsibility.
- Browser
- Waiting for response
- Application
- Result: book row
- Local data source
- Read complete
- The HTTP response was prepared
The application prepares a JSON representation and 200 status. The browser has not received this response.
- Browser
- Waiting for response
- Application
- 200 + JSON ready
- Local data source
- Read complete
- Response headers reached the browser
fetch() may resolve when status and headers are available. The body need not be complete and the DOM need not be updated.
- Browser
- 200 headers; body pending
- Application
- Response sent
- Local data source
- Read complete
- The body was read and interpreted
Application code awaits a separate async body read such as response.json(). JSON being available does not automatically update the card.
- Browser
- 200 JSON ready; UI unchanged
- Application
- Response sent
- Local data source
- Read complete
- Application code updated the UI
Code reads the body and updates the DOM. HTTP receipt and the UI update are separate stages.
- Browser
- UI: Atlas Notları
- Application
- Request complete
- Local data source
- Read complete
Record missing
- The intent starts in the browser
The intent to open a book has not reached the server. Other actors do not know this request.
- Browser
- Card pending
- Application
- No request
- Local data source
- No query
- The HTTP request arrived
The method and resource selection reached the application. No record has been read yet.
- Browser
- Waiting for response
- Application
- GET /api/book received
- Local data source
- No query
- The handler runs locally
The application selects a route, interprets input and prepares a read. This stage is not another network message.
- Browser
- Waiting for response
- Application
- Handler → readBook
- Local data source
- No query
- The read reached persistence
Data access in this example is a local call in the same process. The separate card shows logical responsibility, not another database host or network packet.
- Browser
- Waiting for response
- Application
- Waiting for read result
- Local data source
- readBook request received
- The data layer determines a result
This controlled case has no record. The application will choose the HTTP status later.
- Browser
- Waiting for response
- Application
- Waiting for read result
- Local data source
- Result: no record
- The read result is in the application
The application received the result; serialization and HTTP status selection are its responsibility.
- Browser
- Waiting for response
- Application
- Result: null
- Local data source
- Read complete
- The HTTP response was prepared
The application prepares a JSON representation and 404 status. The browser has not received this response.
- Browser
- Waiting for response
- Application
- 404 + JSON ready
- Local data source
- Read complete
- Response headers reached the browser
fetch() may resolve when status and headers are available. The body need not be complete and the DOM need not be updated.
- Browser
- 404 headers; body pending
- Application
- Response sent
- Local data source
- Read complete
- The body was read and interpreted
Application code awaits a separate async body read such as response.json(). JSON being available does not automatically update the card.
- Browser
- 404 JSON ready; UI unchanged
- Application
- Response sent
- Local data source
- Read complete
- Application code updated the UI
Code checks the status and displays a not-found message. A 404 does not necessarily reject the fetch Promise.
- Browser
- UI: book not found
- Application
- Request complete
- Local data source
- Read complete
ACTORS · STATE · DATA FLOW
The work started by entering a URL
A URL such as https://books.example/catalog contains a scheme, host and path. The browser treats it as navigation to a document. When needed it obtains DNS information, uses an IP route to the destination and establishes an appropriate connection. HTTP/1.1 and HTTP/2 commonly use TCP with TLS for HTTPS. HTTP/3 runs over QUIC and uses QUIC’s TLS-based secure connection. IP routing does not select /catalog’s application handler.
These steps need not restart for each request. DNS results may be cached; suitable connections may be reused; a browser or intermediary cache may provide the response. A reverse proxy can accept a connection on the origin’s behalf, and a CDN can serve an eligible cached representation without reaching the origin. A fixed URL→new DNS→new TCP→new TLS→database chain is therefore not a universal event trace. Later lessons expand the conditions.
Navigation and fetch() do different jobs
Navigation connects the received document to construction of a new page; its resources can trigger further loads. Our Atlas Notları screen is already open. Its button uses fetch() for /api/book?case=found. That call does not automatically replace the current document; the program receives a Response and decides how to present the result.
The relative API URL resolves in the existing document’s URL context. Our 127.0.0.1 plain-HTTP lab needs neither public DNS resolution nor a TLS handshake for this request. The scene starts with delivery to the handler; it omits Internet routing, DNS, TLS, proxy and cache hops. Omission from this scene does not mean those layers are absent from web requests generally.
What the handler receives and does
The method is GET, the path /api/book, and the query selector case=found. The selector chooses a benign scenario supplied by the teaching application. The handler chooses the route, recognizes the selector and asks its storage adapter to look up a book. Route selection is local processing, not another HTTP request.
The adapter returns a record or a missing result. This lab stores seed data in memory: the call and return stay in one process. A production driver may use another host and protocol, while embedded storage can remain local. A flow symbol teaches data movement; it does not claim a captured database packet or SQL-engine execution.
From record to JSON response
For found, the handler puts id and title into a book object, with title Atlas Notları. Serialization produces UTF-8 bytes for a JSON body and a 200 response. Missing has no record and produces a 404 body containing BOOK_NOT_FOUND. This is an HTTP response created by the handler, not a request lost in the network.
The artifact uses HTTP/1.1 text form: status line, headers, empty line and body. Content-Length counts body bytes, not displayed characters; the ı in Notları uses more than one UTF-8 byte. HTTP/2 and HTTP/3 do not use this exact text framing. X-Lab-Request-Id is a custom lab correlation header, not a universal HTTP-service requirement.
A Response does not mean the body has been consumed
fetch() can fulfill with a Response when status and headers are available, before the full body is consumed. A 404 also produces a Response, with response.ok false. The application checks the status; await response.json() separately consumes and parses the body. These are not one promise or one success decision.
Network failures, aborts and unsuitable URLs can reject fetch(). Even after a Response is available, reading can fail or invalid JSON can prevent parsing. Seeing 200 does not prove JavaScript obtained valid application data. HTTP success, body parsing and business-valid data are separate conditions.
Data in memory; a changed view is another step
Parsing produces a JavaScript object in browser memory. The found branch writes title as text into a DOM heading; the missing branch chooses a not-found view. The browser updates the image in its rendering work after DOM mutation. fetch() is not a DOM API, and receipt does not automatically update the book screen.
Separate server response creation, HTTP status/header receipt, body consumption and DOM update in the scene. Motion represents arrival, and a receiver must not obtain data before it arrives. Step controls explain state; they do not claim every real body arrives in one packet or rendering frame.
2. Red · Trust & Impact
Read every scenario without motion
Field boundary
- A request carries a selection
The browser prepares GET for a book card. case is this example’s data selector, not an identity field granting a user authority.
- Browser
- GET /api/book?case=found prepared
- Application boundary
- Request not received
- Representation owner
- Fields not selected
- The input boundary was reached
The application received GET. The path selects the route and the case query selects an approved found/missing scenario; recognizing that selection does not verify browser identity or permission.
- Browser
- GET /api/book?case=found prepared
- Application boundary
- GET /api/book?case=found received
- Representation owner
- Fields not selected
- A local result is not output
The seeded memory adapter call stays in process. record-found or record-missing is handler knowledge, not yet browser data.
- Browser
- Waiting for response
- Application boundary
- record-found
- Representation owner
- Fields not selected
- The representation boundary was set
This fixture emits only book.id + book.title. Reading a record does not require serializing all server data; no additional private field is claimed to exist here.
- Browser
- Waiting for response
- Application boundary
- 200 JSON prepared
- Representation owner
- 200 / book.id + book.title
- Response arrived; interpretation is separate
The browser received the 200 response. Fetch fulfillment alone does not establish business success; body reading and status checks are separate.
- Browser
- 200 + JSON received
- Application boundary
- 200 JSON prepared
- Representation owner
- 200 / book.id + book.title
- The UI preserved the boundary
Code uses status and the JSON contract together. The card displays only book.title; response delivery and DOM changes remain separate stages.
- Browser
- UI: Atlas Notları
- Application boundary
- 200 JSON prepared
- Representation owner
- 200 / book.id + book.title
Record absent
- A request carries a selection
The browser prepares GET for a book card. case is this example’s data selector, not an identity field granting a user authority.
- Browser
- GET /api/book?case=missing prepared
- Application boundary
- Request not received
- Representation owner
- Fields not selected
- The input boundary was reached
The application received GET. The path selects the route and the case query selects an approved found/missing scenario; recognizing that selection does not verify browser identity or permission.
- Browser
- GET /api/book?case=missing prepared
- Application boundary
- GET /api/book?case=missing received
- Representation owner
- Fields not selected
- A local result is not output
The seeded memory adapter call stays in process. record-found or record-missing is handler knowledge, not yet browser data.
- Browser
- Waiting for response
- Application boundary
- record-missing
- Representation owner
- Fields not selected
- The representation boundary was set
The handler prepares 404 with error=BOOK_NOT_FOUND for the absent record. It produces no book.id or book.title; this is an HTTP response, not network loss.
- Browser
- Waiting for response
- Application boundary
- 404 JSON prepared
- Representation owner
- 404 / BOOK_NOT_FOUND
- Response arrived; interpretation is separate
The browser received the 404 response. Fetch fulfillment alone does not establish business success; body reading and status checks are separate.
- Browser
- 404 + JSON received
- Application boundary
- 404 JSON prepared
- Representation owner
- 404 / BOOK_NOT_FOUND
- The UI preserved the boundary
Code uses status and the JSON contract together. BOOK_NOT_FOUND is an ordinary absent-record outcome, not a successful book card.
- Browser
- UI: not found
- Application boundary
- 404 JSON prepared
- Representation owner
- 404 / BOOK_NOT_FOUND
ASSUMPTION · BOUNDARY · CONTROL
A client selection is not server authority
The button sends a selector; the handler evaluates its closed list of scenarios. A client “found” label is not authoritative storage state. Identity, ownership or price labels in other applications likewise cannot become verified solely by arriving from the client.
The broken assumption is substituting query/body input for authoritative server state. Impact depends on accepted fields and actions. This public book-read scene does not prove private-resource permissions or write safety.
The limits of a success label
HTTP 200 is a protocol outcome, valid JSON a parsing outcome, and the right book a business outcome. Merging them into one success flag can show incorrect data or stale UI state. Treating 404 as a network exception obscures the intended missing branch.
Separate status, content type, body shape and UI branch. Protected resources also need trusted handler/service authorization; frontend branching does not replace it.
Traces must not disclose their own data
A requestId can correlate handler and browser observations. Logging every body can move private data or credentials into another store. Obtaining debug data differs from deciding who may read it.
This artifact contains synthetic book data and field names. Real products define minimal events, access policy and retention. Secret-free traces do not themselves prove a safe browser response; inspect both output surfaces.
3. Blue · Secure development & defense
Read every scenario without motion
Evidence matched
- Read the response sample
The found response sample contains status 200, X-Lab-Request-Id and a JSON body, produced by the handler. This artifact does not measure browser receipt of those bytes; browserExpected separately describes the expected flow.
- HTTP response sample
- demo-book-found / 200
- Trace evidence
- Trace not read
- Correlation review
- Outcome unknown
- Producer evidence was read separately
In the synthetic trace, the handler produces request-received, route-selected and response-created; storage-adapter produces local-lookup and record-found. in-process-call identifies this read’s local boundary.
- HTTP response sample
- demo-book-found / 200
- Trace evidence
- seq 1…5 present
- Correlation review
- Outcome unknown
- Correlation scope was established
X-Lab-Request-Id and requestId are correlation fields of this application fixture only. demo-book-found links this interaction; similar names do not merge other operations.
- HTTP response sample
- Response sample present
- Trace evidence
- requestId matched
- Correlation review
- Same interaction
- The body contract was inspected
The body carries book.id and book.title; its 53 UTF-8 bytes are not a character-count claim. response-created does not substitute for browser delivery evidence.
- HTTP response sample
- 53 bytes / JSON
- Trace evidence
- response-created: 200
- Correlation review
- Body matches; UI separate
- The expected view stays separate
browserExpected.view=book-title is the expected view choice. The model displays Atlas Notları, but this artifact contains no actual DOM observation. Body correctness and the learner’s screen are different evidence.
- HTTP response sample
- Model UI: Atlas Notları
- Trace evidence
- Trace is separate evidence
- Correlation review
- Expected view kept separate
- Outcome and unknowns were separated
Response status, JSON fields and the custom requestId agree with the trace. 404 plus BOOK_NOT_FOUND belongs to the separate missing branch. This comparison does not establish browser delivery or an actual DOM update.
- HTTP response sample
- Response/body consistent
- Trace evidence
- Trace consistent
- Correlation review
- Response/trace agree; DOM unmeasured
Trace missing
- Read the response sample
The found response sample contains status 200, X-Lab-Request-Id and a JSON body, produced by the handler. This artifact does not measure browser receipt of those bytes; browserExpected separately describes the expected flow.
- HTTP response sample
- demo-book-found / 200
- Trace evidence
- Trace not read
- Correlation review
- Outcome unknown
- Producer evidence was read separately
Application trace entries request-received and response-created describe separate production stages. This branch deliberately omits the trace portion; absence is not evidence of an attack.
- HTTP response sample
- demo-book-found / 200
- Trace evidence
- Trace absent
- Correlation review
- Outcome unknown
- Correlation scope was established
X-Lab-Request-Id and requestId are correlation fields of this application fixture only. Without a matching trace, the handler path is not verified.
- HTTP response sample
- Response sample present
- Trace evidence
- Trace absent
- Correlation review
- Incomplete coverage
- The body contract was inspected
The body carries book.id and book.title; its 53 UTF-8 bytes are not a character-count claim. response-created does not substitute for browser delivery evidence.
- HTTP response sample
- 53 bytes / JSON
- Trace evidence
- Trace absent
- Correlation review
- Body matches; UI separate
- The expected view stays separate
browserExpected.view=book-title is the expected view choice. The model displays Atlas Notları, but this artifact contains no actual DOM observation. Body correctness and the learner’s screen are different evidence.
- HTTP response sample
- Model UI: Atlas Notları
- Trace evidence
- Trace absent
- Correlation review
- Expected view kept separate
- Outcome and unknowns were separated
The response sample body and expected view are known, but the missing trace leaves the handler path unknown. Handler and storage-adapter evidence must be requested for the same requestId scope; response status cannot fill the gap.
- HTTP response sample
- Response/body consistent
- Trace evidence
- Request missing trace
- Correlation review
- UNKNOWN: handler path
IMPLEMENTATION · SECURITY CONTROL · VERIFICATION
Read Network and application traces together
Inspect target, method, status, response headers and body in DevTools. Link X-Lab-Request-Id to the handler trace; its name is a lab contract. Application events reveal route selection, local lookup and response creation, not captured storage packets.
Timing helps distinguish receipt from UI mutation. Observe the DOM title or missing message separately. The Network panel does not reveal database internals; do not confuse it with source traces or adapter observations.
Found, missing and incomplete evidence
Found expects 200, JSON book.title and that title in the DOM. The benign missing case expects 404, BOOK_NOT_FOUND and a not-found view; fetch() still provides a Response. This intended negative branch is not an attack alarm.
A status without requestId or trace leaves handler ordering unknown. A response-created trace without browser receipt distinguishes creation from delivery. Parsing failure can leave an old book on screen; inspect loading/error UI states before concluding from 200 alone.
Explainable consistency checks
Compare the local contract: found→200+book, missing→404+error. Each response body’s UTF-8 byte count matches Content-Length, and the custom requestId matches the trace. This check belongs to the fixture schema, not a universal detector.
Durable handling preserves failure stages: network, status, parsing and DOM branch. Trace correlation identifiers are allowed, session secrets are not. Regression covers both found/missing and ensures stale data is not presented as success after parsing failure.
NOW APPLY IT TO THE CASE
Are a request, server outcome and browser observation the same?
When Atlas Notları exists, the card expects a 200 response with book.title. A missing book instead produces 404 and BOOK_NOT_FOUND. Server preparation, browser receipt and a changed card are separate stages.
The linked case shows a 200 response and a JSON parsing failure. Identify where receipt, body consumption and DOM update diverge, and describe the missing evidence.
Open the related case file ↗READ THE EXAMPLE TOGETHER
Two HTTP outcomes and local processing traces
Select a field and examine what it supports and where the evidence ends.
Read the raw artifact and field explanations
{
"representation": "HTTP/1.1 teaching text, CRLF-delimited; selected headers only",
"storageTransport": "in-process-call, seeded memory",
"exchanges": [
{
"case": "found",
"requestId": "demo-book-found",
"request": "GET /api/book?case=found HTTP/1.1\r\nHost: 127.0.0.1:4175\r\nAccept: application/json\r\n\r\n",
"response": "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: 53\r\nCache-Control: no-store\r\nX-Lab-Request-Id: demo-book-found\r\n\r\n{\"book\":{\"id\":\"book-atlas\",\"title\":\"Atlas Notları\"}}",
"bodyUtf8Bytes": 53,
"trace": [
{
"seq": 1,
"actor": "handler",
"event": "request-received",
"requestId": "demo-book-found"
},
{
"seq": 2,
"actor": "handler",
"event": "route-selected",
"route": "/api/book"
},
{
"seq": 3,
"actor": "storage-adapter",
"event": "local-lookup",
"transport": "in-process-call"
},
{
"seq": 4,
"actor": "storage-adapter",
"event": "record-found"
},
{
"seq": 5,
"actor": "handler",
"event": "response-created",
"status": 200
}
],
"browserExpected": {
"fetch": "fulfilled-with-Response",
"status": 200,
"ok": true,
"body": "await response.json()",
"view": "book-title"
}
},
{
"case": "missing",
"requestId": "demo-book-missing",
"request": "GET /api/book?case=missing HTTP/1.1\r\nHost: 127.0.0.1:4175\r\nAccept: application/json\r\n\r\n",
"response": "HTTP/1.1 404 Not Found\r\nContent-Type: application/json\r\nContent-Length: 26\r\nCache-Control: no-store\r\nX-Lab-Request-Id: demo-book-missing\r\n\r\n{\"error\":\"BOOK_NOT_FOUND\"}",
"bodyUtf8Bytes": 26,
"trace": [
{
"seq": 1,
"actor": "handler",
"event": "request-received",
"requestId": "demo-book-missing"
},
{
"seq": 2,
"actor": "handler",
"event": "route-selected",
"route": "/api/book"
},
{
"seq": 3,
"actor": "storage-adapter",
"event": "local-lookup",
"transport": "in-process-call"
},
{
"seq": 4,
"actor": "storage-adapter",
"event": "record-missing"
},
{
"seq": 5,
"actor": "handler",
"event": "response-created",
"status": 404
}
],
"browserExpected": {
"fetch": "fulfilled-with-Response",
"status": 404,
"ok": false,
"body": "await response.json()",
"view": "not-found-message"
}
}
]
}- request / response
- HTTP/1.1 teaching representation, not raw DevTools capture; an empty CRLF line separates headers and body.
- Content-Length / bodyUtf8Bytes
- Body octets without compression, potentially different from Unicode character count.
- X-Lab-Request-Id / requestId
- Custom example correlation field, not an HTTP standard.
- trace[].actor / event / transport
- Server processing and local adapter calls, not network protocol records.
- browserExpected
- Distinct expected outcomes for HTTP Response, body reading and view.
Synthetic selected-header representation, not a complete RFC-compliant server transcript or claimed lab output. Date and other browser headers are omitted. HTTP/2–3 framing, packetization, DNS/TLS and real persistence are not modeled. If the real lab uses another correlation header, its implementation contract governs.
Two reality checks
A server 404 automatically rejects the fetch() promise.
404 is an HTTP Response: fetch() may fulfill with response.ok false. The application checks status separately.
Receipt of a response means the screen has updated.
Status/headers, body consumption/parsing and DOM update are separate stages. fetch() does not itself mutate the DOM.
YOUR TURN
Work through this story.
Predict the outcome, find the evidence boundary, and explain it in your own words.
In the missing case, 404 response headers reached the browser. The body has not been read. What is expected at this point?
- fetch() resolves with a Response; status is 404 and ok is false.
- fetch() automatically rejects because the status is 404.
- The error text has been written into the DOM because headers arrived.
Read the explained answer
fetch() resolves with a Response; status is 404 and ok is false. — The selected fixture turns a missing record into a 404 with a JSON error body. Headers/status can be available before response.json() completes; the view update is another local operation.
Within what boundaries does the server trace below establish browser knowledge and the storage path?
Selected server stages from the found case; synthetic teaching record
- actor / event
- storage-adapter / local-lookup → record-found
- transport
- in-process-call
- handler / status
- response-created / 200
- It shows a local lookup and response construction; browser delivery cannot be inferred from this trace.
- A packet sent to a separate database host is proved because a storage card exists.
- The book title is visible in the DOM because a 200 was created.
Read the explained answer
It shows a local lookup and response construction; browser delivery cannot be inferred from this trace. — This trace correlates application processing. It does not measure client delivery, so browserExpected describes an expected flow rather than an observation.
A colleague says “the row was found, so the user saw the book.” Explain two missing boundaries using the found case.
Read the explained answer
Record-found is only a data-layer outcome. The handler must separately construct an HTTP response and deliver it to the browser. Once a Response arrives, its JSON body must be read and parsed; the script must write the title into the DOM. This fixture supplies no DNS/TLS or paint-completion observation.
□ I separated the server outcome from browser response delivery.
□ I explained body parsing and DOM updating as separate steps.
□ I did not claim DNS/TLS/paint outcomes that the fixture does not measure.
Open the application console · request / response / browser
Also open request, URL, cookie and DOM examples
MANUAL LAB
Request, session, and resource policy
Two workbooks follow actual loopback HTTP requests, cookie/store boundaries, and seeded permission decisions.
Open the prediction → observation → explanation workbook ↗Source on GitHub ↗Sources and scope
- MDN — How the web worksClients and servers · The other parts of the toolbox · So what happens, exactly?
- RFC 9110 — HTTP Semantics3.1 Resources · 3.2 Representations · 3.3 Connections, Clients, and Servers · 3.7 Intermediaries · 8.6 Content-Length · 15.5.5 404 Not Found
- RFC 9112 — HTTP/1.12.1 Message Format · 9 Connection Management · 9.3 Persistence
- MDN — Using the Fetch APIHandling the response · Checking response status · Reading the response body
- WHATWG Fetch StandardFetch method · Body mixin · HTTP-network-or-cache fetch
- WHATWG HTML — Browsing the webNavigation and session history · The navigate algorithm
- RFC 8446 — TLS 1.31 Introduction
- RFC 9114 — HTTP/32 HTTP/3 Protocol Overview
- OWASP Authorization Cheat SheetIntroduction · Validate the Permissions on Every Request · Verify that Authorization Checks are Performed in the Right Location
- OWASP Logging Cheat SheetEvent data sources · Event attributes · Data to exclude · Verification