Your shopping is done. The last item has been placed into your cart, you’ve checked out and now you wait for your goodies to be delivered. Know what you’ve just done? You’ve been an unwitting participant in an Event Driven Architecture (EDA)!
According to Gartner, the technical definition of an EDA is:
“A design paradigm in which a software component executes in response to receiving one or more event notifications. EDA is more loosely coupled than the client/server paradigm because the component that sends the notification doesn’t know the identity of the receiving components at the time of compiling.”
In an EDA there are two participants: Publishers and Subscribers. A publisher sends messages (or “event notifications,” in technical terms) because it needs to know something or have some action taken. The Publisher has an expectation that there is at least one Subscriber who will receive its messages, but it does not know nor does it care who or where that receiver is. The Subscriber, on the other hand, sits around waiting for messages that it knows how to handle. When it receives a message, it processes it and may or may not respond to the message by publishing its own message(s). In our shopping example, you are the Publisher. You, via the website’s software, sent a message (your order), to the merchant. The merchant is the Subscriber. They receive your message, process it by picking, packing and shipping your goodies, and send you a message in response to let you know when your goodies will be delivered.
Why EDA rather than a Request/Response Architecture (RRA)?
Most services (micro, macro, nano, pico, wherever) have traditionally employed an RRA. While effective, there are some properties of an RRA that an EDA improves upon:
- In an RRA, there is a one-to-one relationship between the Publisher and Subscriber. Only one Subscriber will ever receive a message. In an EDA, there’s a one-to-many relationship. Any number of Subscribers can receive the same message and process it in different ways. This is a form of parallel processing without having to write any threading code.
- In an RRA the Publisher is stuck waiting for a response, even if it does not require one. This means the Publisher can do nothing else while waiting for a response. In an EDA, the response, if any, is returned to the Publisher in the form of another message in which case the Publisher is also a Subscriber. Much more efficient for the Publisher as it can do other things while waiting for a response.
- In an RRA, there is tight coupling between the Publisher and Subscriber. If the Subscriber is unavailable for any reason, the Publisher will not get a valid response and it is then the responsibility of the Publisher to implement complex processes like retry and rollback. In an EDA, the Publisher simply fires off a message and as long as the message is accepted by the messaging layer, the Publisher is done. If a Subscriber is unavailable, it’s not the Publisher's concern. When a Subscriber becomes available the messages that are waiting to be processed are processed. There is no retry logic and fallback is only required on the Publisher's part if it does not receive an expected response within an expected time limit. This allows for fewer complex Publishers and therefore cleaner, easier to maintain code.
A Picture is Worth a Thousand Words
- The Web App in our example publishes a Submitted Order message/event. The Submitted Order message is picked up by the Order Validator service.
- The Order Validator service applies business logic to ensure the order can be processed. If it can, it publishes a Validated Order message. If it cannot, it publishes an Invalid Order message which will be picked up by a Support service.
- Three services: Customer Notification, Order Picker and Shipper Notification each receive a copy of the Validated Order message and process the messages in parallel.
- The Customer Notification service publishes an Order Confirmation message that is picked up by the original publisher and notifies the User that their order is being processed.
EDA is not a new concept. It’s been employed for years in all kinds of systems that had access to a messaging layer. What has made it more prominent of late has been the advent of the Cloud and highly-distributed computing. For the most part, until just recently, the messaging layer was limited to a single network or data center. With Cloud-based messaging however one company’s application can easily publish a message to another company’s application on the other side of the planet. Talk about decoupled! This allows Application Architects to take advantage of processes that they cannot or do not want to develop and deploy themselves.
Like every other architecture, EDA is not for every situation, but it should be considered when you want to design and build an application:
- whose User Experience can be made much more responsive via asynchronous processing of requests to the services layer (i.e. Reactive)
- that employs a Contract First design paradigm whereby the development of one service is not held hostage to development of a related service.
- in which business processes can be changed quickly because there is no single, monolithic process choreographer that needs to be modified and tested. New capabilities can be added ad-hoc by simply deploying new services that consume messages that are already being published.
I am planning two more blog posts that will discuss two design patterns for implementing an EDA: