4.3 Asynchronous Request–Reply
Asynchronous two-way communicationThis pattern is based on Request–Reply by Hohpe et al. [4, p. 147, 60], Asynchronous Request–Reply by Microsoft [61], Asynchronous Request–Response by Hohpe [62], Request-Response Communication by Newman [3, p. 104], and partly on the Messaging pattern by Richardson [20, p. 87, 59] and the Decoupling Middleware pattern by Nygard [12, p. 117].
The patterns have varying implementations but share the same structure and purpose. An overview is given below.
See also Message Broker.
4.3.1 Context
Synchronous messaging has become a bottleneck, but using only Publisher–Subscriber (see § 4.2) or Queue-Based Load Levelling is not an option, as either
The client expects a response
One of the communicating parties cannot use a messaging broker due to technical limitations (e.g. a web browser), or when long-running connections are not feasible
4.3.2 Solution
There are three potential ways to implement this pattern.
Use a message broker (see § 7.2) and configure two queues: one for the request and one for the response. The sender sends a message to the request queue and waits for a response on the response queue.
Use synchronous communication to send the request, then use polling to check for a response on a pre-determined endpoint. This option is less efficient as there will be more communication overall, but it might be easier to implement with existing infrastructure or tools. The receiver can improve efficiency by replying with an estimate on the request completion [61].
Use synchronous communication and a callback mechanism. The sender sends a request and a callback address. The receiver processes the request and sends the response to the callback address. [62]
4.3.3 Potential issues
Compared to synchronous communication, this pattern brings increased latency and complexity. If implemented using synchronous calls, Retry logic (see § 7.3) might need to be employed to handle transient failures.
Using synchronous communication is faster, simpler and more efficient if the requirements allow it.
Using this pattern to communicate with multiple parties may result in requests being processed out of order. This can be mitigated using a Correlation Identifier [4, p. 154, 63].
See also § 4.2.3.
4.3.4 Example
Creating an order in ExampleEshop is a complex operation implemented as a distributed transaction, which can take longer than the timeout of a synchronous call. However, they want to provide feedback to the user as soon as possible. Still, these updates do not have to be long-term, as analytics showed that users stop refreshing the page once they receive confirmation that their payment is through and an estimated delivery time.
Thus, for a simple implementation, they opted to poll the server periodically to check the order status in the initial phases when many changes are happening. Once the order is confirmed, the frontend stops polling and informs the user that they will receive further updates via email.
4.3.5 Related patterns
While not necessary, Queue-Based Load Leveling can be used to improve handling peak demand
Retry logic might be necessary if using synchronous communication
4.3.6 Further reading
- Request-response on Wikipedia [64]