Designing application using Event Sourcing.

We use database for storing application state. If we need to figure out how application reached a particular state then we have to build auditing system and store history in database.

Event Sourcing makes auditing easy.

Basically Event Sourcing means storing all changes to application state as a sequence of events in database and then using these events to derive current state of application.

Auditing is one of many benefit provided by Event Sourcing Architecture.

Other benefit includes:

1. Going back in time to correct history.

2. Regenerating current application state from history.

I will try to explain using an example for better understanding.

First I will tell you how I design a application without Event Souring, what issues I faced and how these issues I could have avoided by using Event Sourcing.

Last year (when I was not familiar with Event Souring) I wrote a application which generates bills for utility and maintain balance of utility.

So my Model structure looks like:

class Utility
field :balance
has_many :bills
end
class Bill
field :reading_at_start
field :reading_at_end
field :net_arrears
field :amount
belongs_to :utility
end
class Payment
field amount
belongs_to :utility
belongs_to :bill
end

(There were others fields as well , I have omitted them for simplicity.)

Every month a rake task run which generates bill for all utility for duration of a month. Utility balance is set as (-) negative bill amount.

Admin user does payment entry for bill, payment amount to added to utility balance .

If partial payment is done then utility balance bill be negative amount which will get added to net_arrears of next month bill.

This setup works fine for first few months but then there were issues:

2. There were some wrong payments done for previous month bill which needs to reversed. This will make current bill invalid because net_arrears is . not added in current bill.

With current implementation doing payment for previous bill and deleting payments for previous bill is not possible therefore we disabled payment for previous months bill and for deleting payments for previous month bill we have to follow certain steps manually

How did Event Sourcing have solved these issues.

At the time of generating bill, add BillGeneratedEvent

class BillGeneratedEvent
field :reading_at_start
field :reading_at_end
field :amount
field :generated_at
field :applicable_at
belongs_to :utility
end

At the time of bill payment, add BillPaymentEvent

class BillPaymentEvent
field :amount
field :generated_at
field :applicable_at
belongs_to :utility
end

With this setup, we can delete all bills for utility and regenerate it from BillGeneratedEvent & BillPaymentEvent

Now when payments is done for previous month bill then add BillPaymentEvent, delete all bills and regenerate bill using BillGeneratedEvent & BillPaymentEvent.

Other Advantage of this setup is that I can show utility balance history logs very easily. I just have to sort Events on applicable_at field and apply :amount to balance. For BillGeneratedEvent deduct :amount from balance and for BillPaymentEvent add :amount to balance.

Where should we use event sourcing ?

If your application needs auditing then event sourcing is the right Architecture for you.

Conclusion:

Event Sourcing can help us in building robust application. Give it a shot in your next project.

Ref:

--

--

Senior Engineer @ Rakuten Viki

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store