Originally aired on
July 10th, 2016
We spend much of our time as developers managing the state in our applications. There are many different approaches and philosophies attributed to reading, mutating and storing state.
The Event Sourcing pattern is an approach to managing application state. If we think of any given state of our app as a frame in a video, Event Sourcing allows us to scrub through past states of the app. Today we discuss what Event Sourcing is and how we can start integrating it into our PHP apps.
Event Sourcing is thinking of application state as a frames in a video, we could "scrub" through different states of the application.
Every time something happens that is relevant, you just record what it was, then you tie to it, any extra details that are really necessary to understand what happened. Then later you can turn those events into state, by running one after another to see how they stack up.
So basically it's recording what happened, then generating state from those records.
Accounting, as in a bank ledger. You wouldn't just update the balance after a transaction occurred on an account, you store a record of the transaction that then the state of the account is based on the summing of the transactions.
Simple CRUD apps are probably not a good candidate for using this type of approach. Generally, you would want to use Event Sourcing when you need a record of something, when you need to know what happened and in what order, AND when there is a delay of time between events. Something with good amount of complexity, or necessity to audit, or complex decision making, so that you can go back and figure out what happened. Things like Data Mining, where you are looking to see behavior over time to influence marketing. Legal requirements.
In comparison to a typical CRUD style of app, where data is stored in a database and we can think about our data, like Users in a Users table, Event Sourcing will have an id (usually UUID) and a field to indicate which order the events happened. Often people store Meta data as well. The Action is the first class citizen and the Data is the second class citizen.
It's not necessarily the Action, as much as the Effect that gets recorded. So for example, Borrowing a Book, you would have a command called
BorrowABook, and you would store "A book was loaned out to user X".
Snapshotting, instead of loading all millions of events, you look for the most recent snapshot, and grab all the events that happened after the snapshot.
Snapshotting doesn't seem to be too necessary, it seems rare to have something that has a lot of events that would be processor heavy enough to require snapshotting, but it is a potential way of handling situations where an object may have many many events.
The general idea for CQRS is to have separate models for different purposes. So far we have been discussing Event Sourcing as a way to persist your main business objects, so in the example of a Borrowed Book, you could replay the events into a Books table, that's the point where you would have a Read model and a Command model. So when you need to make a change to a books status, you would write to the Command model...and anytime you wanted to display that information, you would get that through the Read side.
This is sort of the plumbing for Event Sourcing. You generally start with a simple Command object, that then gets passed on to a Command Bus, that then figures out the CommandHandler, that then figures out which Object you actually want to change and passes the data from the Command to the actual Object. The actual Object is the one that is going to contain the data or raise the proper events.
Some of this can be accomplished in other languages using AOP (Aspect-Oriented Programming).
Another thing about Commands and Events, from a high level, is that Commands are expressing intent for something to happen. So you are asking to "Register a User". You don't necessarily know that a User is going to be Registered as a result of that command, commands can fail and do all sorts of things. Commands, CommandHandlers, Events, and EventHandlers are different but only subtly.
People tend to try to Event Source their entire applications. Event Sourcing has a cost, and it is beneficial to limit it to the parts of your application that it is going to provide the most benefit to you.
There is a lot to build in order to do Event Sourcing and CQRS, that is not talked about a lot. There is a lot of "plumbing" that has to be built in order to Event Sourcing. It's really up to you to decide if your business will benefit by having the flexibility that CQRS offers.
Also, people tend to conflate things into Event Sourcing. The Command Bus, Read Models, Projects, aren't actually Event Sourcing, but rather patterns that go well with Event Sourcing to the point where they are almost the de facto way to Event Source, but there tends to be a lot of confusion about that.
Generally, adding a new feature in a couple years time, if you have kept enough change along the way, you are often able to do that in an Event Sourced application. In a way you can future proof the application to be able to use the data that you are gathering now, which you may not necessarily know you need at this point.
A fundamental consequence of sourcing your state from your events, is that you don't any data. Everything that you have Event Sourced, you have, going forward.
Generally, you can use a lot of storage that you can think of because of the nature of an Event Store. Like you don't modify records, you just add records over and over again. Most Databases are not optimized for that, but it's also not usually a big deal.
The mentioned Event Store solution provides a way to process events in to new event streams, which is probably the biggest benefit of it over a more common database store.
Thank you, Marijn Huizendveld for sharing your knowledge on event sourcing. A $50 Amazon gift card from Laracasts is on its way to you.
Thank you Andy Huggins for authoring the show notes for this episode!
If you'd like to contribute show notes and totally get credit for it, check out the show-notes repo!