There are a lot of articles that talk about Event Driven, but most of them do not give real and practical benefits of using it. This article aims to give a real and clear example.
What is an Event Driven Approach?
Event Driven is a way to organize your system's code and architecture. When writing event-driven software, the code emits some events that will be consumed by other code or services.
It decouples the pieces of code that emit events from those that consume it, making it easier to maintain and scale.
Woovi
Woovi is a Startup that enables shoppers to pay as they like. To make this possible, Woovi provides instant payment solutions for merchants to accept orders.
To accept instant payments, Woovi receives a webhook for each of the merchant's received payments.
Woovi Transaction Sync
The picture above illustrates the new transaction payment workflow.
In this workflow, the bank sends a new transaction to Woovi's backend.
Inside Woovi's backend, we have the transactionSync
code that processes the new transaction and saves it.
transactionSync
is idempotent, to avoid duplicating transactions when a webhook is triggered twice.
It also updates the status of existing transactions if needed. It needs to handle different types of transactions, like payments, refunds, or withdraws.
What is a Webhook/Postback URL
A Webhook/Postback URL is an HTTP endpoint that receives a new request when a new event happens.
Transaction Sync without Event Driven
If we don't follow an event driven approach inside transactionSync
code, for each event we'd have to call the responsible function inside transactionSync
.
When a new payment
happens, we can call newPayment
function. When a refund is confirmed
. Then same happens for withdrawal.
Here is an analysis of what happens when we use this approach:
- If
newPayment
is slow, it will slow downtransactionSync
- If
newPayment
breaks, it will breaktransactionSync
- To code
newPayment
you need to understand howtransactionSync
works, more cognitive load - To test
newPayment
, you need to testtransactionSync
together, as a consequence you have a more complex test with more complex fixtures and test scenarios. - To refactor
newPayment
, you could breaktransactionSync
, these codes are highly coupled. - We can't easily just reprocess
newPayment
without reprocessing the wholetransactionSync
Transaction Sync with Event Driven
In this approach, instead of calling directly the function to process the event. The transactionSync
will only emit these events that will be processed by another function, job or service.
Here is an analysis of what happens when we use this approach :
- If
newPayment
is slow, it won't slow downtransactionSync
- If
newPayment
breaks, it won't breaktransactionSync
- To code
newPayment
you don't need to understand howtransactionSync
works, fewer cognitive load - To test
newPayment
, you do need to testtransactionSync
together, as a consequence you have simpler test scenarios with simpler fixtures. - To refactor
newPayment
, you won't breaktransactionSync
, these codes are highly decoupled. - We can easily reprocess
newPayment
without reprocessing the wholetransactionSync
Event Driven in JavaScript
At Woovi we use bull for distributed jobs and messages using Redis. If you are starting a fresh codebase, or moving to event driven approach, we recommend to use bullmq which is a modern version of bull.
Drawbacks
One drawback of this approach is that you need to have a queue system that will manage your events, and call your distributed jobs to process them.
To sum it up
Following an event driven approach even without using microservices can bring a lot of benefits to your codebase. It makes it clear which events are important for your product.
It decouples code. Furthermore, it makes it easy to retry processing events.
Finally, it makes refactoring easier; tests become simpler, and removing the temporal coupling of some code becomes possible
If you wanna work with us, we are hiring!
Top comments (0)