In this post, I will be explaining what are the benefits of event-driven architecture. I will be doing this by explaining some of the problems with request-driven architecture and how event-driven architecture solves these problems.
Note: you can also watch the YouTube video version of this post.
Example: A website using Stripe Checkout for taking payments
And I will be doing this by going through the following example where we have
- A Website, an online shop. Which for collecting Customers payments it uses stripe the payment processing platform, payment page within the checkout process
- An checkout service which the website calls when the customer is ready to checkout, before the stripe payment t page is shown. It also expose a public api which Stripe will call when it?s taken payment or payment failed.
- An Order Fulfilment service which needs to be triggered after Stripe has successfully taken payment.And first This service will be triggered using point to point requests from the checkout service This service updates the customer?s account, triggers processing of the order and notifies the customer by email that there order has been successful.
When the customer is ready to checkout.
The website will call the checkout service before showing the customer the payment page because first we need to generate and store a identifier which we will send to stripe , which we will use later once payment has been taken.
Now we call Stripe to create the Stripe checkout session passing the identifier we created and stored in a field called client_reference_id.
And stripe will return with its checkout session id.
Which we will return to the website and we show the customer the Stripe payment page. .
Now the customer fills in the payment with their payment details and we call Stripe to complete the payment, passing in the stripe checkout session id.
Once Stripe has taken payment it will use a webhook to notify the checkout service that payment was successful.
Now the checkout service will now request the order fifilment service to fufil the order and notify the customer.
And once the service has completed fulfilling the order the checkout service will notify Stripe that it has handled the request. And stripe will notify the customer.
Request-driven architecture is not fault Tolerant
But what happens if the fulfilment service encounters an error, or its unavailable and you start to have errors bubbling upstream to the checkout service which is handling the webhook from Stripe. Leading to your system not able to process the order correctly, which could mean that the customer?s account information may not reflect what has happened. leading to an increase in support requests, customer dissatisfaction and an impact on the brand.
Now to be clear. Stripe will redirect the customer to your success page after 10 seconds if your system does not respond, or returns a failure. Stripe will also retry calling your system later.
But how can you make your system more resilient?
Introducing event notifications
And this is where we utilise event-driven architecture and use event notifications.
Now we are going to introduce a messaging platform where the checkout service will publish messages to when it receives the event from Stripe.
And Once a message has been published successfully , the webhook handler would then respond that it has handled the request from Stripe.
Now the fulfilment service would subscribe to the events, and once an event exists, it would then consume and process the event.
Now the checkout service, and the fulfilment service are now decoupled from each other, which now means that the checkout service no longer needs to wait for the fulfilment service to complete and respond back. As the fuilment event is now handled asynchronously
And what if the fulfilment service is not running or encounters an error. Well the checkout service would not be affected and still respond to Stripe that it has successfully handled the event.
And when the fuilment service resumes it will process the events which are waiting.
So as you can see by changing the triggering of the order fulfilment service to be from request driven (point to point), to event-driven, decouples and makes the two services Independent from each other. And this lose coupling and independence introduces the following benefits.
Benefit: Fault Tolerance
An increase in fault tolerance.
Benefit: Time independence
And time independence for processing, because now the checkout service no longer waits for the fulfilment of the order. And the fuilment service can process events when it?s ready.
Increase in service independence
And the increase in service independence can have additional benefits in development where individuals and teams can develop, deploy and release services without depending on other services to be available.
Testing can be done in isolation because you have clear boundaries of the responsibility of each service.
The services are triggered by a message, they process the message, and they publish the outcome.
And this can all easily be tested.
Another benefit is extendability because now you have the events, everything which needs to know about an event can, without developers having to change publishers to notify each service.
Also a publisher does not care if 1 or a 100 consumers are listening for events, nor will it affect performance of the publisher, because a publisher only needs to publish a message once
So event notifications enables the ability to plug in and swap out services independently, and this allows you to architect an incremental/evolutionary, guided, architecture. And the keyword is guided.
For example, you could release functionality which publishes state changes for objects one month. Then the next month release functionality to start consuming those events and perform actions on them.
So we have discussed that event-driven architecture brings lose coupling, which brings fault isolation and fault, fault tolerance, independence and extensibility by decoupling services with events.
But what does this enable and what benefits does this bring to an organisation, well this is hard to explain because it can enable solutions to problems which weren?t possible before.
You can break apart monolithic services into smaller services, microservices or functions to enable quicker development.
You can replace entire systems without having to touch other systems.
You can plug on new business processes in a fraction of the time it would have cost, without event-driven architecture.
You can take advantage of concepts and patterns of event streaming, where you can process data in real-time. This has enabled better fraud detection, and the ability for companies to react to trends and opportunities in seconds.