Request Lifecycle
Purpose: Detailed step-by-step trace of an incoming HTTP request through Webspresso's middleware pipeline, router, data loaders, template engine, and response stream.
1. Sequence Diagram #
View diagram source
sequenceDiagram
autonumber
actor Client as Browser / Client
participant Express as Express / HTTP Server
participant ReqId as Request ID & Context MW
participant Auth as Dual Auth MW
participant Router as File Router
participant Hooks as Lifecycle Hooks
participant Loader as Route load()
participant Engine as Nunjucks Engine
participant Compress as Streaming Compression
Client->>Express: HTTP Request (GET /products/123)
Express->>Compress: Initialize zlib streaming buffer (1KB threshold)
Express->>ReqId: Assign req.id (X-Request-Id) & populate req.context
Express->>Auth: Authenticate Session Cookie / JWT Bearer
Express->>Hooks: executeHook('onRequest', ctx)
Express->>Hooks: executeHook('onRoute', ctx)
Express->>Hooks: executeHook('beforeMiddleware', ctx)
Express->>Router: Match Route (pages/products/[id].njk)
alt SSR Page Route
Router->>Loader: Call load({ req, res, db, ctx })
Loader-->>Router: Return data { product, title }
Router->>Hooks: executeHook('beforeRender', ctx)
Router->>Engine: Render template with data & fsy helpers
Engine-->>Router: Compiled HTML string / stream
Router->>Hooks: executeHook('afterRender', ctx)
Router->>Compress: Stream HTML chunks
Compress-->>Client: 200 OK (Brotli/Gzip Compressed HTML + X-Request-Id)
else JSON API Route
Router->>Router: applySchema(req, compiledSchema)
Router->>Router: Execute API handler(req, res, ctx)
Router-->>Client: 200 OK (application/json + X-Request-Id)
else Route Error / 404
Router->>Hooks: executeHook('onError', ctx)
Router->>Express: Enrich error with trace metadata & propagate to Central Error Boundary
Express-->>Client: 404 / 500 Error Page or JSON (with trace in dev)
end
2. Step-by-Step Lifecycle Phases #
Phase 1: Transport & Connection Edge #
- TCP Connection & Draining Check: The server checks if it is in shutdown draining mode. If shutting down, new requests are rejected immediately with HTTP 503 (
Service Unavailable). - Streaming Compression (
server.compression): The zero-dependency streaming zlib interceptor inspects theAccept-Encodingheader (br,gzip,deflate). Payloads below the 1 KB threshold bypass compression; larger payloads stream through zlib transform streams.
Phase 2: Context & Auth Initialization #
- Request Correlation & Context Container:
req.idis extracted fromX-Request-Id(orX-Correlation-Id) or generated viacrypto.randomUUID(), and mirrored in response headerX-Request-Id.req.contextis initialized containing{ req, res, db, app, serviceRegistry }.req.service(name, input, opts)is attached to allow calling business services directly from route handlers.
- Dual Authentication:
- For stateful web requests: Built-in native cookie session populates
req.sessionandreq.user. - For stateless API requests: The JWT middleware extracts
Authorization: Bearer <token>, verifies the HMAC-SHA256 signature, and populatesreq.auth.
- For stateful web requests: Built-in native cookie session populates
Phase 3: Lifecycle Hooks & Route Resolution #
- Global & Route Hooks:
onRequest(ctx): Invoked before route matching or middleware execution.onRoute(ctx): Invoked once the target route path is identified.beforeMiddleware(ctx): Invoked before executing page-specific middleware.
- Route Matching:
- Linear-time lookup matches the request URL against pre-sorted
RouteTabletiers (static paths take precedence over dynamic:idsegments, followed by catch-all*).
- Linear-time lookup matches the request URL against pre-sorted
Phase 4: Execution & Rendering #
- SSR Data Prefetching (
load()):- If the page exports an
async function load({ req, res, db, ctx })ordefinePage(), it executes server-side. - The returned data object is merged into the template context.
- If the page exports an
- Nunjucks Rendering / JS Page Output:
beforeRender(ctx)hook fires.- The template compiles with access to layout blocks, page assets (
pageAssets), localized translatort(), and thefsyhelper catalog (fsy.asset,fsy.csrfToken,fsy.route). afterRender(ctx)hook fires.
Phase 5: Error Boundary & Tracing #
- Async Error Propagation & Trace Enrichment:
- All async route methods and loaders are wrapped in auto-catch handlers.
- Unhandled rejections are annotated with execution context (
route,method,source,module,phase,requestId). - In development mode (
NODE_ENV !== 'production'), errors render high-visibility terminal banners and output a structuredtraceobject. - In production (
NODE_ENV=production), 500 error stack traces and internal diagnostics are safely masked for security.