Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Reactive HTTP service client: the proxy returns a publisher, not a completed call

Last updated: 1 Oct 20264 min read
tutorial
IntermediateBy AITrove Editorial

An HTTP service interface backed by WebClient starts remote work on subscription and inherits cancellation and timeout behavior.

Subscription owns the attempt

A method returning Mono<PriceQuote> can describe a remote request without sending it yet. If two callers subscribe independently to a cold result, two HTTP attempts may occur. If the downstream commits a write, repeating subscription has the same uncertainty as a retry. Keep a stable command ID for writes and avoid hidden subscribe calls inside handlers.

Cancellation is not a remote rollback

A browser disconnect or timeout can cancel the local publisher after the request reached the remote service. The remote side may still complete. For read-only calls, cancellation mainly affects resource use and latency. For a write, reconcile by command ID or query a durable result. Reactive transactions protect local database work in their chain; they cannot roll back a separate HTTP service.

Make the boundary testable

Back the interface with a WebClient adapter, then test against a stub that delays a response and records received requests. Subscribe twice and count attempts; cancel after the server receives a POST and verify the application reports uncertainty rather than false failure. The code creates a proxy but does not supply production timeouts or authentication.

Implementation sketch

Java
@HttpExchange("/v1/prices")
interface ReactivePricingClient {
    @GetExchange("/{sku}")
    Mono<PriceQuote> quote(@PathVariable String sku);
}
var adapter = WebClientAdapter.create(webClient);
var client = HttpServiceProxyFactory.builderFor(adapter).build()
    .createClient(ReactivePricingClient.class);

Cost and verification

Non-blocking I/O can support many pending calls with fewer request threads, but each active call still consumes a connection and buffers. Timeouts and concurrency limits remain necessary.

Common Mistakes

  • Do not call subscribe inside a controller and return before the remote result is known.
  • Do not assume cancellation undoes a remote write.
  • Do not reuse a cold publisher as though it were a cached result.

Read next

Spring HTTP service client: the interface is a contract, not a transport policy, Spring HTTP service client retries: an interface cannot prove the server did not commit, Spring WebClient exchangeToMono: decode the response inside its callback, Spring reactive transaction: subscription owns the context, not a thread.

spring
spring-boot
web-apis
reactive-http-service-client
Storage details