The PHP podcast where everyone chimes in.

Originally aired on

July 10th, 2016

049: Event Sourcing in PHP

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.

with


Event Sourcing in PHP Show Summary


What is Event Sourcing?

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.

Real World Example

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.

Good Use Cases for Event Sourcing

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.

How to think about the data

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".

How to handle an object that has millions of "events"

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.

How does CQRS relate to Event Sourcing?

CQRS - Command Query Responsibility Segregation

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.

Command and CommandHandler and Events and EventHandlers

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.

Common Pitfalls

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.

What value does Event Sourcing provide?

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.

Is there any particular approach to storing this data?

Event Store is a open source, functional database with complex event processing in JavaScript. Is this a preferred way to store events (or to process them) vs MySQL, Mongo, or other?

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.

Recommended Resources for PHP

Beau Simensen


Ross Tuck


Shawn McCool


Willem-Jan Zijderveld


Developer Shout-Out

The Developer Shout-Out recognizes developers in the community for their contributions.

For this episode the panel guests, Beau, Ross, Shawn, and Willem-Jan nominated Marijn Huizendveld for the Developer Shout-Out segment.

Thank you, Marijn Huizendveld for sharing your knowledge on event sourcing. A $50 Amazon gift card is on its way to you.

$50 Amazon gift card sponsored by Laracasts

Laracasts

It's like Netflix for developers.

Show Notes Credit

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!