Michael HönnigMichael Hönnig
In my experimental side-project, Gleanius [1], a microlearning app, I am using Event-Sourcing [2] and CQRS [3, 4]. This turned out to be an extremely good decision because several times I later found out that new features needed more information in my read model. And the great thing was that in most cases the information was already available in the Event-Store [5]. And as was using my own app as soon as possible in early development, this way I was able to access this information not only fore new data, entered after knowing about the new requirement, but even for existing data. All I needed to do, is to extract the newly needed data from the existing events, while rebuilding the read model; which by the way is no code for one-time use, as many import functions are, but needed anyway for building the read-model. In some cases, though, a new feature needed new data which was not in my events. But in all cases, the data was available in the actual originating command, I just wasn't smart enough to store it along with the event because at that time I had no use for this data.

Examples

1. When I wanted to improve the Spaced Repetition [6] algorithm, I needed the information how long the last and longest period of remembering a topic was and for which length of period the learner had failed to remember in the past and how often this ha happened. The Event-Store already contained each event of the learner answering the quizzes, including whether it was correct or wrong and a time stamp, thus all I had to do, was to extend the read-model-builder to extract this information on a per-topic level. 2. Another day I want to extend a multiple choice game where I wanted to confront the learner with terms which he had confused in earlier exercises. The app once knew about which answers were given wrong but I did not store this data, as I had no use for it at that time. Thus, the information was lost for past events; all I could do was to start storing this data along with new events.

Conclusion

Event-Sourcing is a great preparation for new requirements, but only if you are smart enough to store all data along with the events, which belong to the business case from which it stems. Just not needing the data at that time should not be a reason, not to store it. You can omit it in your read-models as long as it's not needed, but once it is needed, you can simply add it to the reducers - et voilá - your application can use it.

Legal Note

One warning, though: Data privacy laws might prohibit storing data which is not actually needed (at the time of storing the data). his principle is called "data avoidance" or "data minimization" (in German: "Datensparsamkeit"). But that only applies to personal data and in most cases can be legalized by putting the rules into your terms of usage. Ask your lawyer for more details!

Comments?

If you like, you can leave a comment on Twitter, thanks!
[1] https://gleanius.com [2] Event Sourcing is an Software Pattern where all changes to the state of a software system are recorded as events as a primary data source in a way that it's possible to re-create any past state of the software system. [3] CQRS (Command query responsibility segregation) is a design principle which uses separate data-structures to update and and modify data. [4] To be honest, my usage of this pattern in Gleanius is limited to the app internals so far, as I've not yet implemented any server-side queries except a full restore. [5] An Event-Store is a software module which stores immutable events in the context of Event-Sourcing. [6] Spaced Repetition is a learning technique that applies increasing intervals of time between subsequent review of previously learned material in order to make learning more efficient.