DEV Community

Cover image for Practical Benefits of an Event Driven Approach
Sibelius Seraphini for Woovi

Posted on

Practical Benefits of an Event Driven Approach

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

Webhook Workflow

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

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 down transactionSync
  • If newPayment breaks, it will break transactionSync
  • To code newPayment you need to understand how transactionSync works, more cognitive load
  • To test newPayment, you need to test transactionSync together, as a consequence you have a more complex test with more complex fixtures and test scenarios.
  • To refactor newPayment, you could break transactionSync, these codes are highly coupled.
  • We can't easily just reprocess newPayment without reprocessing the whole transactionSync

Transaction Sync with Event Driven

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 down transactionSync
  • If newPayment breaks, it won't break transactionSync
  • To code newPayment you don't need to understand how transactionSync works, fewer cognitive load
  • To test newPayment, you do need to test transactionSync together, as a consequence you have simpler test scenarios with simpler fixtures.
  • To refactor newPayment, you won't break transactionSync, these codes are highly decoupled.
  • We can easily reprocess newPayment without reprocessing the whole transactionSync

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)