Request-Reply
Request-Reply pairs a request message with its response over messaging by using a reply-to channel and a correlation identifier, giving RPC-style two-way exchange while keeping the decoupling of messaging. It requires timeout handling because a reply may never arrive.
The Request-Reply pattern enables two-way conversation over a messaging system that is fundamentally one-way. A requestor sends a request message on one channel and expects a reply message on another. It brings RPC-style interaction to asynchronous messaging while preserving decoupling.
The problem it solves is the need for a response. Many interactions require an answer: a query, a command that returns a result, a validation. Plain messaging is fire-and-forget, so request-reply layers a response mechanism on top, pairing each reply with its originating request.
How It Works
The requestor sends a request on a request channel and specifies, usually via a reply-to header, where the response should go. The replier processes the request and sends a reply on that return channel. To match a reply with the right request — essential when many requests are in flight — each request carries a correlation identifier that the replier copies onto the reply.
The reply channel may be shared (all replies come back on one channel, sorted out by correlation id) or private (a temporary per-requestor channel). The requestor can wait synchronously (blocking until the reply arrives or a timeout fires) or handle the reply asynchronously via a callback.
request{ correlationId: X, replyTo: Q } --> replier
replier --> reply{ correlationId: X } on Q --> requestor
When to Use It
Use it when a sender needs a result but you still want the decoupling, buffering, and resilience of messaging — for example asynchronous RPC, service queries over a bus, or command messages that report outcomes. It is the messaging analogue of a synchronous call.
Avoid it when fire-and-forget suffices, and reconsider it when ultra-low-latency synchronous calls are needed, where direct RPC or HTTP may be simpler.
Trade-offs
Request-reply adds correlation handling, reply-channel management, and timeout logic, because the reply may never come. Holding requestor state while awaiting a reply complicates scaling, especially for synchronous waits. It reintroduces a degree of temporal coupling. The benefit is two-way semantics with the reliability and decoupling of messaging.
Related Patterns
It depends on the Correlation Identifier to match replies to requests. It uses Message Channels (often point-to-point) for both directions. When fanning out and collecting many replies, it combines with a Recipient List and an Aggregator (scatter-gather).
Example
A service publishes a PriceQuoteRequest to a request queue with correlationId=abc and replyTo=quotes.reply.123. The pricing service computes the quote and sends a PriceQuoteResponse with correlationId=abc to that reply queue, where the original requestor matches it to the pending request and resolves the call.