Event Driven Architecture, The Hard Parts : Events Vs Messages

Naresh Waswani
Simpplr Technology

--

Teams new to Event-Driven Architecture often encounter confusion distinguishing between “Messages” and “Events.” Both constructs utilize asynchronous communication, facilitating decoupling of services, ensuring swift response times, and inherently promoting scalability.

This blog aims to distinguish between the two constructs, aiding in making informed decisions on when to use each. Let’s delve into the details.

1) Information Carried

Both Message and Event carry some information for other services to consume but the intent with which a message or event is sent makes the difference here.

An Event carries an information which is a Fact, a state change — something which has happened in the Past where as a Message contains a request to be executed by another service. This request could be to perform some action (think as command) by a target service or to get some data (think as query) from a target service.

Content Service publishing an Event (Fact) — A Content has been published
Order Service sending a Message (command) to Payment Service to get the payment done against an order

2) Communication Topology

Events are broadcasted for other services to consume and typically use Publish Subscribe pattern. Kafka is one of the most popular products which supports this pattern. Traditional Message Brokers also provides Topics construct for implementing this pattern.

Messages are point to point interaction between the two services. Queue constructs from Traditional Message Brokers or AWS SQS can be used to implement this pattern.

Broadcast Vs Point to Point Communication Topology

3) Ownership

Both Events and Messages carry some information (think payload) and will be sent to a Broker Channel (Queue or Topic) for other services to consume but who gets to decide what data is sent in the payload and which channel it gets published?

In case of Events — the underlying Channel (Topic) on which events will be published and the event payload will be owned by the Publishing service. In the example above, when a new Content gets published, on which Channel it gets published and what will be payload of the event is owned by the Content Team.

In case of Messages — the underlying Channel (Queue) on which messages will be published and the message payload will be owned by the Receiver service. From the example above, Payment service decides on which channel (Queue) one should send the message to and what details one needs to send for Payments to be initiated.

4) Processing Expectation

In the case of Events, the producer has no clue if anyone is listening to the event for processing and is least interested in who is listening and consuming the events. It does not expect a response to an event and works in a Fire and Forget mode. It publishes the event to a channel (Fire) and continues with its next set of tasks without any response expectation (Forget).

But in case of Messages, the producer expects the message to be processed by the target service as it knows the service to whom the message is sent. Depending on the business requirement and user experience, the producer may choose to block for the response or it may continue to process the next steps and wait for the response to come in an asynchronous fashion.

Let’s take this example to understand this better— Order Service accepts the Order placement request from the user -> sends a point to point message to the payment service for making payment -> responds back to the user that your order has been accepted.

Payment service at a later stage -> sends payment processing response to the Order service using point to point communication -> Order service processes the message and sends an email notification to the user, confirming if the order was successful or it failed because of payment error.

Order Service using Asynchronous Notification Pattern for Order Placement Use Case

This looks so logical, why would one get confused?

The confusion arises when you start implementing workflows where multiple services are involved. Let’s see a simple use case —

As part of GDPR compliance, you want to implement ForgetMe use case at the Tenant level in your Multi Tenant SaaS product which is built using Event Driven Microservices Architecture. You have multiple Domain services including a Notification Service which is Horizontal in nature.

One of the simplest way to implement this use case is to use Event mechanism —

Using Events to implement ForgetMe use case

In the above implementation, Tenant Manager service publishes a TenantDeleted event for others to consume and react. Because Notification service is also listening to the same event, it sends an email confirming the Tenant has been successfully deleted — but in reality, the Tenant data may or may not have been deleted by then. And that’s the catch here.

Also, as part of business requirement, Tenant Manager service has to ensure that all the domain services must delete (or anonymize) Tenant specific data. For this, it has to keep a track of all the services which maintain tenant specific data, and also needs an acknowledgement from these services that data has been deleted. And only then, the Notification service should send the notification to the Tenant Admin that your data has been deleted.

So there is a concern of sequence in which things need to be executed to meet the business requirement. And also, the producer service must know the target services which need to perform the required action which goes against the principle of Event Driven Architecture.

With Events, because all the consumers react in parallel, controlling the sequence is tough. Messages help to achieve this sequential execution when needed.

So the revised way of getting this use case implemented is —

Using Messages to implement ForgetMe use case

Tenant Manages sends messages to individual domain services to take an action. And only on receiving confirmation from all the domain services using Asynchronous communication pattern, the Tenant Manager service sends a message to the Notification Service to notify the Admin user.

By the way, in this case, if you realize, the messages sent to all the Domain services carry the same payload. And only Notification service will have a different payload. So, there can be hybrid approach to implement this —

Using Hybrid approach of Event + Message to implement ForgetMe use case

Tenant Manager fires a TenantDeletedEvent -> all the domain services react to it and confirms the status using Asynchronous notification pattern. And once the Tenant Manager service has a confirmation from all the domain services -> it sends a message to the Notification service to notify the Admin user.

I hope this blog has given you enough clarity on the constructs of Events and Messages in the context of Event Driven Architecture and which one to leverage given a situation.

Hope you enjoyed reading this blog. Do share this blog on social media if this has helped you in any way.

Happy Blogging…Cheers!!!

#EventDrivenArchitecture #Events #Messages #Microservices

** This blog is inspired by technical contents published by two of my favorite authors — Neal Ford and Mark Richards.

--

--

Naresh Waswani
Simpplr Technology

#AWS #CloudArchitect #CloudMigration #Microservices #Mobility #IoT