# ADR-002: Request ID Injected via logz Context Helpers **Status:** Accepted **Date:** 2026-03-18 ## Context Each HTTP request should carry a unique identifier that appears in log records, error responses, and the `X-Request-ID` response header, so that a single request can be traced across log lines. There are two sub-problems: 1. **Generation and storage**: the middleware must generate an ID and make it available to downstream code via the request context. 2. **Retrieval for logging**: `RequestLogger` must be able to read the ID from the context to include it in log records. The naive approach — store the ID under a locally-defined context key — breaks interoperability with `logz.Logger.WithContext`, which enriches log records with values stored under `logz`'s own unexported key. If a different key is used, logz cannot find the ID, and it does not appear automatically in structured log output. ## Decision The `RequestID` middleware calls `logz.WithRequestID(ctx, id)` to store the generated ID in context. `RequestLogger` calls `logz.GetRequestID(r.Context())` to retrieve it. Both functions use the same unexported key inside the `logz` package, guaranteeing that the value stored by `RequestID` is the same value retrieved by `RequestLogger` and, more importantly, by any `logz.Logger` downstream that calls `WithContext`. The ID is also written to the `X-Request-ID` response header at the middleware level, so clients can correlate responses to requests without parsing log files. ## Consequences - Any `logz.Logger` in the request chain that calls `.WithContext(ctx)` automatically inherits the request ID as a structured log field — no manual plumbing required. - The generator function is injected by the caller (`RequestID(generator func() string)`), keeping the ID format flexible (UUID, ULID, or any string). - If the same request ID is sent in the `X-Request-ID` request header, it is ignored by `RequestID` — the middleware always generates a fresh ID. Preserving inbound IDs is a separate concern that should be handled explicitly if required. - This design requires `httpmw` to import `logz` directly (see ADR-001 for the justification of that exception). - Global ADR-003 (context helpers live with data owners) is directly applied here: `logz` owns the request ID context key because the request ID is a logging concern, not an auth or business concern.