Event sourcing: making it functional (5)

TL;DR

After defining events of the Payment aggregate it’s time to move on and work on applying these events.

State

To apply events, the state of Payment will be extracted to a separate class. This should be a familiar pattern to all event sourcing practitioners, but let me show the code for clear understanding of our approach

paymentstate

How to construct the state

  1. There are no public setters. The state has readonly properties.
  2. All events are applied with an Apply method.
  3. The only way to change the state is to apply an event.
  4. No Apply throws an exception. The event has already happened and the state is just an accumulator of the changes.

New Payment Aggregate

The Payment aggregate now can be transformed to use this state, by removing all the state changes and raising/applying events in these places:

paymentstate

Summary

We know how to extract a state from the aggregate and apply all the events. Although Payment uses events, it does not store them in any form nor allows accessing them for processing. In the current shape the Payment isn’t much different from the previous version. We extracted a few event classes and the state, but we still can’t treat events as the first class citizen. we need to move one step further and we will do it in the next blog post.

Zapraszam na szkolenie z EventSourcingu: Warszawa, 16-03-2017

Zapraszam Was na moje szkolenie otwarte dotyczące EventSourcingu w .NET!

Tematem zdarzeń zajmuję się od dawna i nastał czas aby podzielić się tą wiedzą z Wami w formie szkolenia. Rejestracja odbywa się przez system Evenea na tej stronie i tam też znajdziesz wszystkie informacje.

Strona szkolenia

Jeżeli wahasz się i chciałbyś zobaczyć mnie w boju przed szkoleniem, zapraszam na moją jutrzejszą prezentację na Warszawskiej Grupie .NET, pt.

Keep Its Storage Simple Stupid,
an opinionated guide to NoSQL with Windows Azure Storage and Event Sourcing

Podczas niej omówię pewne aspekty projektu w modelu SaaS, w którym zastosowałem zdarzenia i Event Sourcing do obsłużenia złożonej domeny biznesowej. Dla uczestników spotkania przygotowałem też mały prezent związany ze szkoleniem 😉

Do zobaczenia!

Event sourcing: making it functional (4)

TL;DR

In the last entry we defined the aggregate implementation that we’ll work on. Let’s move forward and make it an event sourced aggregate.

Events

The first and the most important event, is the fact of issuing the payment itself. Let’s define it in the following way:

paymentissued

The event contains all the data provided to the constructor of the payment aggregate in the past.

The next one is raised and applied when the payment is processed successfully. Let’s make it a class without any members. We just want to record a notion of success.

paymentissued

The last but not least is the one raised in case of the error. We make the errors explicit in here as we’d like to react to payments failure. One could model it in a different way, providing one event class, but then again, just follow this take on the payment problem.

paymentissued

Summary

We discovered three meaningful events:

  1. PaymentIssued
  2. PaymentProcessedSuccessfully
  3. PaymentProcessedWithFailure

In the next entry we will start rewriting the aggregate to use these.

Event sourcing: making it functional (3)

TL;DR

We’re on our journey to move from event sourcing oriented on the aggregates to a more functional approach. In the first entry, we went through some of the DDD building blocks. In the second, we defined an interface of the aggregate that we’ll work with. Before, going to the event sourced approached, let’s go through the aggregate’s implementation, somehow related to the Blue Book approach, without event sourcing.

Payment aggregate!

Let’s dive straight into the code

paymentapi

We can see that a payment is issued for a user, with a specified payment method and a given amount of money. Yes, it’s simplistic, but bear with me, and follow its implementation for a while.

The other method is responsible for receiving the gateway response and applying it onto the aggregate. The status and the description are updated accordingly.

So far so good? In the next entry we’ll make this aggregate event sourced!

Event sourcing: making it functional (2)

TL;DR

In the last post we covered the basic concept of DDD, the aggregate and its root. Before we move on with the non-functional approach, let’s try to define at least one aggregate, that could be used as an example for future posts and code samples.

A payment

For sake of providing an aggregate example let me reuse the payment example I introduced for the service kata purposes. The aggregate boundary is handling a single payment. This includes:

  • selecting payment method
  • registering an answer from the payment gateway
  • storing status

Having this we can easily imagine that the API of this aggregate could be similar to:

paymentapi

As you can see, there are no dummy setters or meaningless primitive properties. We exposed meaningful methods and properties for showing the part of the state we want to show. Additionally, the payment constructor shows all the parameters that are required to issue a payment.

With this example we can move forward and provide more insight into its initial implementation and refactoring it towards more functional design.

Event sourcing: making it functional (1)

TL;DR

This article starts a series of entries that will guide you through my experiences with making event sourcing functional. There are a few existing entries about a functional approach to event sourcing, but I want to share my path and a story behind migrating from one approach to another. I’ll start with some fundamentals. This will show from where I started, as well as it may help you to learn some basics of DDD and event sourcing if you’re not into the topic.

The Blue Book51szw87slrl-_sx258_bo1204203200_

There’s a book that is a must read, Domain-Driven Design by Eric Evans. It’s quite old and a lot of has changed in our industry. Still, the basic need of having developers understanding the domain they work on, the strategies and tactics they could use to embrace it, they are the same. Eric covers a lot of topics in there, one of them which is a really low level concept (and not the most important one) is the aggregate.

The aggregate

Let me quote Eric’s descriptions of the aggregate first:

An AGGREGATE is a cluster of associated objects that we treat as a unit for the purpose of data changes. Each AGGREGATE has a root and a boundary. The boundary defines what is inside the AGGREGATE. The root is a single, specific ENTITY contained in the AGGREGATE. The root is the only member of the AGGREGATE that outside objects are allowed to hold references to, although objects within the boundary may hold references to each other. ENTITIES other than the root have local identity, but that identity needs to be distinguishable only within the AGGREGATE, because no outside object can ever see it out of the context of the root ENTITY.

The vital part of this description is the boundary. That’s what aggregate is for – to distill boundaries existing in a domain you work on. So once you set a boundary of data changed together, you ensure that they stay together. Additionally, you operate on this data only via the Aggregate Root, which might be treated as the public API of an aggregate, something that others interacts with.

The aggregate boundaries

If an aggregate is defined by its boundaries, one could design a system, that would be just one aggregate. This would enable to access all the data and still have a defined boundary, right? Wrong. What you want to do is to define aggregates following these two simple rules:

  1. aggregates are as big as there have to
  2. aggregates are as small as possible

Aggregates are as big as there have to

The very first rule says that the size of an aggregate is determined by a domain and a model. A domain can require some consistency across different entities, making an aggregate bigger. The same with model. Frequently it’s up to the modeller (a model’s creator) to create bigger or smaller aggregate, but not bigger than needed.

Aggregates are as small as possible

Distilling just one aggregate would mean, that a system can execute one action at a time (when optimistic concurrency applied). This isn’t enough for the majority of applications. Making aggregates small improves your system’s scalability and performance, not to mention your ability to design and model in small chunks.

Summary

This ends the first entry of this series. We recalled the aggregate’s definition and discussed briefly two rules of modelling an aggregate. Still, there’s more to come on our way of making the event sourcing functional. First, we need to visit a non-functional approach.

2017: Microsoft MVP and more

Microsoft MVP

It’s official. I’m Microsoft MVP for Visual Studio and Development Technologies. It’s first time I got this award. I’m truly happy and wanted to thank you:

  • Microsoft for granting me the award
  • My family for supporting me through this year
  • All the members of Warsaw .NET User Group. 2016 was a very good year and we’ll make 2017 even better!
  • All my friends for all the support I received, both in organizing WG.NET meetings and just being there
  • All the groups and conference organizers for having me!

The award doesn’t mean it’s time to rest. Frankly speaking, it’s quite opposite.

More

The new year will bring some changes. The very next post will start a series of posts about making event sourcing functional. Don’t worry if you don’t know the event sourced approach or functional languages. I’ll start from the very foundations and build up on top of it. This might be not considered as a change, as I had a series about RampUp. This time it’s going to be a true series of well connected entries. If you find it interesting, a few series might appear in here.

There’s a new activity that I don’t want to talk to much about right now, but it will be a another game changer. It will take place in March and I’ll announce it in two weeks.

Finally, I’ve added more information about me and my incoming talks. I hope you’ll find it useful.

It’s time to start a brand new year!