CQRS and Event Sourcing at Hull Developers
/Hull Devs is going from strength to strength. Hot on the heels of the talk last month we have another great talk, this time from Mathew McLoughlin who told us all about CQRS and Event Sourcing. At the start of the evening I had no idea what any of this was about. But by the end of the evening I was up to speed.
CQRS stands for Command Query Responsibility Separation. But knowing that doesn't really help you understand it at the start. The Event side of things is a much better place to begin.
If you are implementing something complicated (Mat used hospital admissions as an example) you could do this by having a record for each item in your system. You could fill a patient object full of things like like name, age, whether the patient is in the hospital, their ward number etc etc. Your system could then update these records each time the patient changes state.
This would store the data, but if you work this way a lot of information gets lost. If you want to know which wards a patient has been treated in, then a system structured like this will not be able to tell you. Furthermore, you're not really capturing what is going on, which is that people are arriving in the system and stuff is happening to them. Instead you're forcing users to update small parts of a large data object (the patient record) each time.
Rather than looking for the data you need to store, better to look for significant events in the trajectory of your objects, and build a system that captures these events. When a patient arrives, moves wards, gets test results and finally goes home, you record these events and your system can then then "play through" them to build a picture of the current state of your patient. It's a very nice way to work. Want to find out the state of your hospital last week? Just run the events to that point and stop. This reminded me a bit of "block chain" currencies where the movement of a lump of money is traced from person to person as it is used to pay for things.
Mat suggested "Event Storming" meetings with the customer to identify events and what effect they have on object state. This involves lots of paper, post-it notes and the development of a common language between customer and developer. And sounds like fun.
OK, but what about CQRS? Well, events are a great way to get stuff into a system, but if you want to view the state of your data you have to do a bit of work. The "Command Query Responsibility Separation" part really means that "projections" of the data in response to queries should just consume events and use them to build the view of the data. The storage of the events should be the responsibility of a totally separate process. This makes the design of the system much easier. The only downside is that your view of your system may be a tiny bit behind the times, as your projection updates in response to events, but in a modern implementation this should not be a problem.
It was a great talk, very interesting. Mat has built some C# that demonstrates this which you can find here. I'm looking forward to the next one.