A Quick Guide to Event-Driven Architecture
Coding (Software architecture)
Learn how programs and microservices take advantage of this pattern
In 2018, after a series of attacks, the chain of hotels Marriott notified their customers with bad news.
They said to them that they lost around 383 million records.
Someone connected to their database and stole data and payment details worth millions if not more of dollars.
Over the years, there have been many more attacks, and some of them have done even more damage.
Both as money and data stolen.
Luckily for us, programmers have invented ways to protect this data.
We can now make applications more reliable and secure.
In this post, we will go over the concept of event sourcing and why it is important to put in place an event-driven architecture in your project.
If the security of data and reliability is what you want for your project, let’s jump on this topic!
How does event-driven architecture work?
No matter what type of application you are working on, chances are that it has a purpose and it does something.
This ‘something’ can be for you or something for your visitors.
Programmers divide this action (this something) into 2 different parts.
- Event
- Command
An event is something that happens.
You can think of an event as a customer buying a product or someone booking a restaurant’s table online.
A command is an order that this event expects.
When you order a product from Amazon you want the item to arrive at your doorstep.
If you book a table you want to arrive at the restaurant at a specific time and be ready to be served.
Both events and commands communicate with each other via messages.
These can contain data or take care to notify that something has happened on the application.
Together events and commands form an architecture that we call Event-driven architecture.
Here is a diagram that represents the basic structure of an event-driven architecture pattern.
The Components of Event-driven Architecture
An event-driven architecture has at least 3 components.
The first one is the Producer.
This is the part of your code that retrieve the data and create the message.
Then we have the Consumer.
There can be 1 or many consumers in this type of architecture.
Notice that both sides can be PHP applications or part of a microservice system
The consumer is the one that read the message and does something with that.
It can be the backend or our application saving the booking on the database or a bank backend saving a transaction into an account.
The last part is the broker.
Some of the most famous is Kafka or RabbitMQ
A broker is in charge of connecting the two parts together.
It gathers the message from the producer and sends them to every consumer that is subscribed to listen
This is usually referred to as a Pub/Sub model.
Pro and Cons
Pros
In a normal system, we would have 2 applications.
Let’s call them Service A and Service B
Every time something changes Service A ‘‘talks’’ straight to Service B.
There are many issues with this system.
To start the 2 systems know about each other, they are coupled.
Coupling is very bad in programming and we want to avoid that as much as possible.
Events or messages are perfect to avoid that, in which they live between the 2 services.
This time, instead of sending data to Service B to be processed, Service A creates an event.
In this case Service B listen if an event arrives.
Does not matter if one of the two services is offline or has a problem.
The broker stores the event and keeps it safe until Service B is ready to receive it.
Another great advantage of this system is that events are immutable.
It means that we can add Services C and D to the architecture and the system will still work just fine.
That is because events are stored in the broker.
Cons
After we went through all the advantages of using this architecture let’s see some cons.
The biggest disadvantage of using this system is the performance of the system.
Whereas before we only have 2 systems communicating with each other now we have introduced a broker.
This means there is a third part to maintain.
Another disadvantage is consistency.
When you have a system with 2 communication parts, the communication is straightforward and it happens at the same time.
When the broker is part of the game, it is in charge of storing the messages.
This means that the consumers can retrieve this data whenever they want to.
The message can be processed at the same time or it can happen with days of difference between one another.
When to use Event-drive architecture?
The answer to this question could be banal as “it depends”.
To make this article have a reason I’d want to highlight what are the reasons this choice depends on.
The first thing you need to focus is what is your end goal.
Do you need scalability or prefer to have a performant and fast application?
We saw that not using a broker makes the application faster as there is less traffic during the communication.
Yet this way to work is not as secure and scalable.
Using domain-drive design would be another solution for this gol.
Another question would be, do I need the data coming from Service A on different services?
If there is more than one consumer, like Service B and C in our case, then it makes sense to use a broker.
Store the messages in a queue and keep them until the services haven’t used them.
Conclusion
As you have read this type of architecture is amazing when considering how much advantage it produces to the application.
And especially how reliable it makes it.
The problem is that adding events to a program or a microservices system is never easy to do and errors are always there to be expected.
In the next article, I’ll describe how to add event and RabbitMQ to a Symfony web application.
If you want to learn how to do that and a lot of other interesting things in PHP subscribe to the newsletter
This way when I publish a new article you can be the first to read it.