This summer I spent some time exploring the CQRS (Command Query Responsibility Segregation) / Event Sourcing landscape for PHP. I found a few promising candidates but most projects were not suitable for production. They were either experimental, half-finished, or had maintainers who had no intention ever making them ready to be used in production.

I was determined to find something, though.

The first project I ended up deciding to start working with was Buttercup.Protects from Mathias Verraes. I rather enjoyed the way Mathias designed the project and I found it fit the way I worked quite well.

I eventually got in touch with Mathias to see what his long-term vision was for Buttercup.Protects. In retrospect I should have talked to him about it much sooner. He told me that Buttercup.Protects was not going to be developed beyond its current state.

It was not a complete loss, however. Mathias also said that I should look at his new project Event Centric instead.

Event Centric turned out to be the most promising project I had looked at up to that point. It had a maintainer that was actively working on the project and that had a desire to someday see their project in production. The only downside was the possibility of an API that "may" be be unstable.

In our conversation Mathias had been upfront about the stability of Event Centric's API. Although there was a desire for a more stable API in the future, at that point in time, Event Centric was a fun side project for him. He wanted to use Event Centric to experiment with some ideas and concepts before he committed to an API and backwards compatibility.

I decided that I could live with a somewhat unstable API. I thought that the work required to stay compatible with an API that was a moving target would be worth the risk.

So I went all in. I spent time integrating Event Centric into a few projects and contributed to Event Centric itself. I started researching what it would take to build a naive Event Store since Event Centric didn't have one yet. Things seemed to be going pretty well. For awhile.

By the time I was getting close to finishing my naive Event Store implementation I noticed something strange. Although I knew that Mathias had been working on things over the previous weeks I realized I hadn't picked up any upstream changes in awhile. It turned out that there had been a massive change to the way the project was being managed and the repositories I had been working off of were not being used anymore. To make matters worse this new repository contained sweeping changes to pretty much every API I had been working with.

My head was spinning thinking about how much time and energy it would take to adjust my code (both the projects I had updated to use Event Centric as well as the naive Event Store implementation I had been writing) to work with the new Event Centric API.

I had invested a sizable chunk of time into both Buttercup.Protects and Event Centric as I had considered them both to be best of breed of the available CQRS / Event Sourcing frameworks in PHP. Seeing that I could not realistically use either of them at this point was quite a bummer. There were no other viable options and I could not justify writing my own project from scratch. I needed to take a break, take a few step backs, and consider my options.

As luck would have it I did not have to wait very long before another option presented itself. The Qandidate.com team launched Broadway to the world in August of 2014 (see their launch blog post, "Bringing CQRS and Event Sourcing to PHP. Open sourcing Broadway!"). The biggest selling point for me was that Broadway was said to have been in production for over a year at the time of launch. This sounded very promising indeed.

Since Broadway's launch I am well into development of two projects using Broadway. The only two major components I have not had a chance to deal with yet are Auditing and Sagas. So far I am quite happy with the results!

Each component ships with just one implementation and several components ship with an implementation that uses a technology that is unique to that component. This means that if you want to use Broadway out of the box you will have to setup a variety of services. This may be a barrier to entry if these services are not already in your stack.

Broadway ships with a DBAL backed Event Store. This is simple to setup and configure. It worked well out of the box with MySQL and the tests all work with SQLite.

For Read Models, Broadway ships with an elasticsearch backed Read Model repository implementation. I was new to elasticsearch so this took me some time to get up and running. I would have preferred to have a simpler DBAL or PDO implementation here but it was a great reason to force myself into playing with elasticsearch.

Broadway's Saga component ships with a MongoDB implementation. There are no examples or documentation for how to use Sagas so I have not been able to explore this much.

Having only one implementation shipped for any component definitely gives Broadway the feel of a project spun out of an existing application. When you use Broadway using only out of the box implementations you are getting a glimpse at how the Qandidate.com team's projects are implemented.

The abstractions are all top notch and it does not look like writing alternative implementations for any components will be a problem. I would fully expect to start seeing third-party implementations of these components in the not to distant future.

What would potentially be missing in third-party implementations is the testing that the Qandidate.com team has in place for the implementations that ship with Broadway. All of the code, even all the way down to the integration with the various services, appears to be well tested. The Qandidate.com team set the bar pretty high for production-ready CQRS / Event Sourcing projects for PHP when it comes to testing.

And speaking of testing, the Qandidate.com team ships some great tools for testing your own code. I'm using the CommandHandlerScenarioTestCase extensively and loving it. I've also started to use the ProjectorScenarioTestCase and the ReadModelTestCase.

I'm super happy that the Qandidate.com team decided to open-source Broadway. It has been working extremely well for me and I feel confident that it is stable enough for production and will remain supported for the foreseeable future. Based on the other tools available for building CQRS / Event Sourcing applications in PHP, this is a big deal.

If you are interested in CQRS / Event Sourcing in PHP and you haven't checked out Broadway yet, go do it now! Want to get involved? One great way would be to join the #qandidate IRC channel on Freenode. If you stop in, make sure to say "hi!" to simensen. Also, Qandidate.com is hiring! They are a great company creating great software and are actively contributing to the open-source community!

dflydev is available for consulting on Broadway and CQRS / Event Sourcing projects. We've contributed to Broadway core and have integrated Broadway into multiple projects since it was announced. Visit our services to learn more about how we can help your business and contact us to tell us more about your needs.