February 14, 2013 / by Indu Alagarsamy / In DDD, Messaging /

Be explicit - Commands and Events

In order for the systems we build to be reliable and scalable, it usually involves queueing and messaging. Having removed temporal coupling out of the equation, (Blocking synchronous RPC has its place, but just not everywhere) messaging is an important part of the puzzle.

  • How we classify these messages become important
  • How we communicate between “things” via these messages become important (using the right messaging pattern, ie. request-response, publish-subscribe, and the other 150 messaging patterns described in Gregor A Hophe and Bobby Woolf’s Enterprise Integration Patterns book)
  • And not but least, naming these messages more important.

Types of Messages:

If we can classify messages, then we could classify them into Commands & Events.

There are those that fail:

Commands are messages that can be sent to one specific logical endpoint to fulfill a certain request. The endpoint that handles this message has the ultimate authority to reject or fulfill this request. Therefore it makes sense to name these messages in the active tense, for Example, PlaceOrder

E = mc2:

And then there are those messages that convey a certain something happened that is of significant importance to the business. And are published as a statement of fact. These messages are classified as events. Since these messages convey a certain something happened, it is named in the passive past tense, i.e. OrderAccepted. Since these have a significant importance, there are often multiple parties interested in when this happens. And since multiple parties are acting on this, as soon as it is broadcasted, they cannot be revoked. When you publish the OrderBilled, Shipping is going to ship the items to the customer. There is no oops, no, Order did not get billed without bad consequences.

Tiny business of naming

When naming these messages, i.e these specific commands and events, let’s for one brief moment, throw away all technical details out of the window and focus entirely on the business. Does business understand CreatePdfDocument? Or IPdfDocumentCreated? If the whole purpose of writing software is so that it adds business value, and the software to “align” with the business, then the first step is to use the domain language, language understood by the business rather than use the language we techy geeks love. My seven year old has the right idea, geeks are cool people that solve problems and he kindly gave me a huge compliment. However domain experts in the business know the business and its needs. Techy people try to understand these requirements and come up with their own language and design to convey the same. Ummm, just why is it that we need an extra translation layer? Why not call a spade a spade? Why not describe our system in the language of the domain. Why is OrderPlaced, getting morphed to some type of IPdfDocumentSent? The blue book (aka Eric Evans’ Domain Driven Design) talks about the importance of the Ubiquitous language.

The patterns of messaging and messages that are classified correctly and named right can easily fit into the business of software development and IT alignment!

Example

Let’s say that Orders can be placed via web, mail or phone. Preferred customers get a certain discount Customers are made preferred, if their sales volume exceeds a certain limit.

An extremely over simplified solution : Order system’s endpoint receives the PlaceOrder command (website exposed to customer, internal intranet site that customer service reps use will send the PlaceOrder command) and once it succeeds based on some criteria, publishes the event, “OrderAccepted”

Let’s say the CRM service, listens to the OrderAccepted events. Knows which customer placed what order, and based on the order amount, can publish the CustomerStatusUpgraded event.

The Order service also listens to CustomerStatusUpgraded and CustomerStatusDowngraded events and based on that sets the discount appropriately.

In this model, the order service does not send commands to the CRM to GetCustomerStatus and waits for a response to compute the discount before it can publish the OrderAccepted event. A simple twist of how pub/sub is used here by making the order service listen to the status changed event, removed the need for request/response and made these two parts of the system autonomous. If or when the event is published, the ordering service will upgrade its discount percent. When orders are placed, it will always use what it has to compute the discount.

And a bigger benefit, when business says, “When a customer’s status is upgraded, they get a complimentary fee waived one year Hertz Gold membership” with all that jazz of 3rd party integration with Hertz, all is needed is to add a an endpoint that subscribes to the event and to fulfill business’ request. And the biggest benefit, these new subscribers can be added without having to modify existing working system. And can be upgraded without having to impact other pieces of the puzzle as well.

2014 Indu Alagarsamy. All rights reserved.