Quick answer: A correlation ID is a single value that follows a request through several services, so their logs can be joined into one chain. Mock the header exchange by having the mock echo the ID, generate one when the client sends none, and return a mismatch or a missing value on demand. This lets you verify that the client generates, sends, reads, and logs the ID correctly without depending on a real distributed system.
What a correlation ID does
A request often crosses a gateway, one or more services, and a queue, and each component writes its own log. Without a shared identifier, those entries are hard to connect when something fails. The correlation ID, carried in a header such as X-Correlation-ID or X-Request-ID, gives every hop the same value. It has two common origins: the client generates one and sends it, or the entry gateway assigns one when the header is absent and returns it in the response. The response header usually carries the same value, so a support engineer can take the ID shown to the user and pull the matching logs.
Mock the header exchange
Use conditional responses to control what comes back, and inspect the recorded requests to see exactly what the client sent. Cover the cases below.
| Scenario | Request header | Mock response header | Client expectation |
|---|---|---|---|
| Client generated | ID present | Echoes the same ID | Log that ID |
| Gateway generated | No ID | A newly generated ID | Adopt the returned ID |
| Downstream differs | ID present | A different ID | Follow the documented rule |
| Missing on response | ID present | No ID header | Keep its own ID, no crash |
| Retry | Same logical call | Echoes the value | Reuse or renew per convention |
The mismatch row matters because a real downstream service can replace the value, and the client needs one clear rule for which ID wins rather than silently logging two unrelated values.
What the client must handle
Put ID generation and reading in one middleware layer so the behavior is consistent instead of being rebuilt per request. Generate a unique, well-formed value for each new logical request, send it on the header, and record it alongside the call. When the response carries an ID, read it and follow the agreed precedence, typically adopting the gateway value or keeping the one the client sent. Decide the retry convention up front: reusing the same ID keeps the attempts tied together, while a new ID distinguishes each attempt, and either is valid if the team applies it consistently. A desktop API workspace lets you set these conditional responses, inspect the recorded headers, and assert on each case in the same place. Powerduck works this way, so the header exchange is a fixed set of local responses.
Honest limits
A local mock runs in the desktop main process and verifies one hop of header handling, not the full behavior of a distributed trace. It does not model propagation across many real services, sampling, or a trace standard such as W3C Trace Context, and it does not prove the live services forward the ID or that the logging backend can actually query it. The echo and precedence rules are ones you define, while a real downstream service can truncate, replace, or drop the value. Confirm end-to-end propagation with a small set of genuine requests. Importing a schema does not deploy a backend, and a passing mock run is not evidence about production observability.
Frequently asked questions
What is the difference between a correlation ID and a trace ID? A correlation ID joins logs for one request across services. A trace ID is part of a tracing standard and often carries span and sampling context. They overlap, but the correlation ID is the simpler header-level value.
Who should generate the ID? Either the client or the entry gateway. If the client sends one, the gateway keeps it; if not, the gateway assigns one and returns it. The mock covers both paths.
What happens when the response has no ID? The client should keep the ID it sent and continue without crashing, rather than failing the request or logging an empty value.
Should a retry reuse the same ID? It depends on the convention. Reusing it links the attempts; renewing it separates them. Pick one and apply it consistently so the logs stay interpretable.
The bottom line
Use a correlation ID to connect the logs for a request, and mock the header exchange to prove the client handles the generated, gateway-assigned, mismatched, and missing cases. Keep generation and reading in one layer, define the precedence and retry rules explicitly, and verify real cross-service propagation separately. For more on this approach, see the API mocking guide hub.
Top comments (0)