Showing posts with label event message. Show all posts
Showing posts with label event message. Show all posts

Tuesday, April 8, 2008

When Event Messages are not Ideal

In a recent post, I discussed why we should prefer the use of event messages over command messages. There are however situations where command messages are more appropriate.

Say for instance we have a billing service that has the ability to raise invoices. Let us also say that there in a large number other services in the enterprise supporting business processes that at some point require an invoice to be raised. Let us then assume that the action of raising the invoice is to be exactly the same, or at least remarkably similar in all cases.

Using event messages in this scenario would lead us to having the billing service subscribe to different event messages from a number of different services, all of which resulting in the exact same operation in the billing service. This is is somewhat wasteful as the billing service needs to be aware of and process a large number of event message types.

As the required behaviour of the raise invoice operation will not vary between contexts, the context of the originating process is mostly irrelevant. This makes the raise invoice operation of the billing service highly reusable.

As such, we should strongly consider using a single command message sent by all other services to the billing service to invoke the raise invoice operation.

We need to be careful however that the reuse here is mandated by the business, rather than coincidental. If we find that in the future each of these services start having different needs of the billing service in raising invoices, we will greatly overcomplicate this operation and start needing to update the command message structure and/or billing service implementation to compensate. We start suffering the effects of coupling again.

In the field we tend to find that the context of the originating process influences the behaviour of the target service most of the time. Where it doesn't initially, we tend to find that it does at some point in the future. That is why it is best in general to prefer the use of event messages over command messages.

Wednesday, April 2, 2008

Avoid Command Messages

According to Hohpe and Wolfe in their book Enterprise Integration Patterns, they state that there are three basic types of messages at a semantic level - command messages, document messages, and event messages.

When discriminating between these message types, we are concerned with the semantics of the message name. So for example, a CancelPolicyRequest message is a command message, as it is instructing the service to cancel a policy. A Policy message is a document message, as it contains information about a business document without any context as to what should be done when it is received. And a PolicyCancelledNotification message is an event message as it informs the receiving service that a policy was cancelled, but does not specify what action the receiving service should take in response to the event.

Although command messages do not constitute an RPC interaction, they introduce coupling between services where the other two message types do not. When Service A sends a command message to Service B, Service A is making a decision on behalf of Service B as to what Service B should do in the context of Service A's activities.

The fact that Service A is instructing Service B what to do means that Service A determines what shall be done, whereas Service B decides how it shall be done. This is a subtle but important form of coupling.

Because Service B is performing an operation for Service A, as Service A evolves we may find that Service B is no longer able to meet the needs of Service A. Now we must update Service B due to a change in the needs of Service A. This is the essence of coupling.

The root of the problem here is that Service B's behaviour is being governed by Service A. Service A is making an assumption regarding Service B's behaviour, introducing a dependency.

Moreover, Service B cannot make up its own mind what to do in response to Service A's activities, it must be instructed by Service A.

Consider the case where Service C now must perform some action in the context of Service A's activities. We now need to update Service A to send a command message to Service C as well. Imagine how the complexity here can grow when we have a large number of services!

The solution is to use message types that do not involve instructing a service how to behave. This leaves us with the document and event message types. The document message type tends to appear mostly with the REST style of architecture (which I will discuss in a future post).

With SOA, the preference is to use event messages. In the previous example, Service A would publish an event (such as InvoicePastDueNotification) to which Service B would be subscribed. Upon receipt of the notification, Service B would then make the decision locally as to how to respond to this event; in this case, cancelling the policy. Service B would then very likely publish a PolicyCancelledNotification message, in case other services needed to respond in some way to this event. If the need arose in the future for Service B to respond differently, this would involve only a change in Service B.

If Service C then needed to perform some action (say claw back commissions) in response to the InvoicePastDueNotification message published by Service A, we would simply need to subscribe Service C to the relevant event topic, and then update Service C to behave as needed. Again we have not needed to make a change in Service A.

Here we can see a business workflow occurring that spans multiple services, where the decisions as to how each service contributes to the process are handled locally within each service.

As always however there is a catch. What if in order for Service B to decide how to respond to the event published by Service A, there is insufficient data in the event message? This would mean we would need to update Service A to include more data in the event message - once again we have coupling.

As such, we need to be careful when designing our event messages such that all relevant information regarding the event is included in the message. The needs of the subscribers are not known in advance, so we cannot just include the minimum information in the event message to satisfy the existing intended subscribers.

So in conclusion, prefer the use of event messages over command messages at the service boundary where possible; but take care in the design of your event messages to make sure all relevant information is included.