Message exchange patterns always depend on the characteristics of the transport layer or protocol they use. But one layer above or below, things might look totally different. For example, you can provide asynchronous message exchange patterns on synchronous protocols, and vice versa.
To illustrate, let's look again at the example discussed in the previous section about dealing with unreliable protocols. Even if your transport layer is not reliable, you still can provide an API with a reliable interface (see Figure 10-8).
Figure 10-8. Reliable service call on top of an unreliable protocol
In this figure, the consumer calls a service. The corresponding API blocks until it receives the response (or an exception). Underneath this API, however, the code is more complicated, because the protocol used is not reliable. In this figure, for example, the first request message sent to the provider gets lost. So, after a timeout, the low-level API of the consumer performs a retry. This message is routed successfully to the service provider. Unfortunately, this time the response gets lost, so the consumer performs another retry. This attempt succeeds, and the requested data is finally returned to the consumer.
In this example, the consumer uses an API for a synchronous request/response MEP, while the low-level protocol is a sequence of request/callback MEPs (the consumer ...