Event-sourcing and CQRS at the rescue

## About

The 2015 release of [mix-it](http://www.mix-it.fr), as usually, was a concentrate of useful tech, tip's and tricks to get back home with a bag full of new ideas that you can apply on your favorites projects.

Throughout the good ambience, nice talks and awesome Baos & crepes I've been at the [CQRS workshop](http://www.mix-it.fr/session/1041/agilite-par-le-code-grace-a-cqrs-et-ev...). Such hands-on makes more sense to me than 10 blog articles so I want to explain what I learnt through .. another blog article! I won't talk about the whole CQRS or event-sourcing concepts but only show how an OBM's functionality can be rewritten following these patterns.

## The old and harmful way

The following picture shows how OBM could search all invitations not yet replied for an user. Don't worry, it's not really like that!


cqrs1

Events or meetings are known as a hell to be managed correctly in a computerized system. Because it's time related, some data are user specific, representing a recurrence is painful and its exceptions even more...

To avoid to duplicate any stuff and keep their database terribly rigid, programmers like us have designed for years their data model as many single-concern tables, linked together with some constraints. So much that when you want to know a simple thing like "What are my not yet replied meetings ?" you fall in a bunch of *-joins, sub-queries and SQL conditions. So a simple need can lead to poor performance SQL requests, hard to test and to maintain.

## How CQRS and event-sourcing can kill that complexity

#### CQRS

CQRS can be understood as a data-model pattern. It makes your application writing stuff in different "views" that you want to request later. Those "views" must hold all events needed by the business logic to decide what action should be done when an user interact with.

In this example, creating a meeting, accepting or declining it leads to write on the "meetings" table and in the "calendar_activity" table too. So "calendar_activity" is a view that your application can request in a simple way to know all activities done on a user calendar.


cqrs2

#### Event-sourcing

For its part, event-sourcing would be the code side pattern. It allows to consume all events recorded with the CQRS pattern. Mix-it facilitators have found some well colored pencils to draw some schema that I won't reproduce :) You can find more theoretic explanations on [their slides](https://github.com/DevLyon/mixter/raw/Slide/slide.pdf).

Following the previous schema and to continue my example, the "calendar_activity" table can contains rows like :

| id | user | event_id | action |
| ------- | ------- | ------- | ------- |
| 11 | me@domain | 15 | 'received' |
| 12 | me@domain | 16 | 'received' |
| 13 | other@domain | 15 | 'received'|
| 14 | other@domain | 15 | 'declined' |
| 15 | me@domain | 15 | 'accepted' |
| 16 | me@domain | 17 | 'received' |
| 17 | me@domain | 17 | 'declined' |

The event-sourcing way to figure out what are the "pending invitations" of the user "me@domain" is:

0. Build the aggregate (a simple class) related to the feature "user invitations"
0. Execute the command "listPendingInvitations()" onto the aggregate
0. The aggregate fetch all user's calendar activities (like "SELECT * FROM calendar_activity WHERE user = 'me@domain';")
0. The aggregate construct its "projection" (also call "state") by replaying every activity
0. Then it "decide" what are the "pending invitations" and returns them to the caller.

In this case the aggregate should returns only the event 16.Nike Jordan