A WebClient attribute belongs to one client request; Reactor Context follows a reactive subscription into later or nested client requests.
Spring WebClient attributes versus Reactor Context: choose the right request scope
Keep local policy local
One receipt lookup can tag a request with a routing hint through attribute. An ExchangeFilterFunction can inspect it, but a second request created inside flatMap does not receive that attribute automatically. This is useful for a one-call option such as an audit classification. A correlation value that must reach nested requests belongs in Reactor Context at the outer subscription boundary.
Do not turn context into authority
A request attribute or context value is application metadata, not proof of user permission. The receiving service must still authenticate and authorize its own request. Keep context keys typed or centrally named to avoid collision, and avoid putting passwords or full receipt bodies there. Response ownership] remains with the code that decodes each exchange.
Test a nested call
Issue one client request that triggers another in flatMap. Assert a one-call attribute affects only the first request, then place a trace identifier in Reactor Context and assert both filters see it. Run the test without the context key too; the filter should have an explicit fallback or fail clearly rather than throwing an unexplained lookup error.
Implementation contract
WebClient receiptClient = WebClient.builder()
.filter((request, next) -> Mono.deferContextual(context -> {
String traceId = context.getOrDefault("receiptTraceId", "missing");
ClientRequest tagged = ClientRequest.from(request)
.header("X-Trace-Id", traceId).build();
return next.exchange(tagged);
}))
.build();
Mono<ReceiptView> result = receiptClient.get().uri(receiptUri)
.retrieve().bodyToMono(ReceiptView.class)
.contextWrite(context -> context.put("receiptTraceId", "trace-47"));Cost and verification
Context lookup and one header are small per request. The main cost is accidental metadata loss across manually started subscriptions or a security bug if context is mistaken for authorization.
Common Mistakes
- Do not expect a WebClient attribute to propagate to nested requests.
- Do not use Reactor Context as an authentication decision by itself.
- Do not call subscribe manually in the middle of a chain and assume the original context follows.
Read next
Spring WebClient exchangeToMono: decode the response inside its callback, Spring WebClient status-specific decoding: consume one branch and close the rest, Spring WebClient request audit: log route identity without payload leakage, Spring Security filter chain: authentication, CSRF and request order, Spring behind a proxy: trust forwarded headers only after the edge strips them.
