Our great sponsors
-
InfluxDB
Power Real-Time Data Analytics at Scale. Get real-time insights from all types of time series data with InfluxDB. Ingest, query, and analyze billions of data points in real-time with unbounded cardinality.
-
conduit
RealWorld example backend implementing the CQRS/ES pattern in Elixir and Phoenix (by slashdotdash)
-
WorkOS
The modern identity platform for B2B SaaS. The APIs are flexible and easy-to-use, supporting authentication, user identity, and complex enterprise features like SSO and SCIM provisioning.
Follow along with what I learned while implementing a project named todo_backend_commanded. Its git history reflects the process of migrating from a vanilla Phoenix API to an event sourced solution.
The Commanded hex package is a fabulous CQRS library used by some real companies in production, but it doesn't have a great on-ramp.
I have been curious about the concepts of event sourcing and CQRS for a while— obsessively reading books like Practical Microservices (Garofolo) and Architecture Patterns with Python (Percival, Gregory), along with documentation for libraries like Sequent (Ruby), Commanded (Elixir).
There's an example application called Conduit, which is the source code for an eBook's project, but its guidance is not up to date and the book itself starts with account / user management (a pretty advanced domain). The other resource outside of the package documentation is a 20 minute conference talk from 2018.
Since I already had a Postgres database running, I decided to use EventStore rather than installing and babysitting EventStoreDB. To initialize the database and tables, I ran mix event_store.init and mix event_store.create.
It's a very familiar API that can be implemented in a few minutes with the Phoenix Framework.
This is a testiment to the value and productivity of Phoenix, but the resulting code is just basic CRUD. The views are tied 1:1 with their database-backed Ecto schemas. One thing to note is that Phoenix generates DDD-style contexts. This is unlike Rails, which would produce a typical ActiveRecord sprawl: bloated models directly being accessed and lazily queried across the entire application.