slashdotdash

slashdotdash

Building Conduit - Applying CQRS/ES to an Elixir and Phoenix web app (self-published)

I’m working on a CQRS/ES and Phoenix book for those interested in building an event driven application using Elixir.


The full source code for the application, Conduit, is available on GitHub.

Most Liked

slashdotdash

slashdotdash

Yes, it will be finished. It’s a stuggle to find the time in addition to consultancy, releasing the next versions of Commanded and EventStore libraries, writing documentation and providing support.

slashdotdash

slashdotdash

You have a few options for tracking unsuccessful events:

  1. Create failure events (e.g. AuthenticationFailed) which are included in your event store. Here’s an example in Commanded’s aggregate guide where a failure event (AccountOverdrawn) is created during withdrawal.
  2. Audit your incoming commands, including whether the command was successfully handled or not. You can use Commanded audit middleware to do this. It also tracks causation and correlation identifiers between commands and events allowing you to follow the flow of messages in your app.

In an aggregate, you build state by replaying the events which allows you to track historical values. As an example, if you had a bank account aggregate you could capture the current account balance over time by recording each time it changes (due to deposit or withdrawal events). Similarly, to support a user query you could build a read model from those same events with the balance shown over time as a list of transactions.

The performance will likely depend upon your chosen event serialization format and how fast your Postgres database can write to disk. Appending events is done using a multirow INSERT statement, so it’s relatively fast. The only reliable way to answer the question “is it fast enough for my usage” is by simulating your expected load in your own deployment environment. To get a rough idea you can run the EventStore benchmark suite (MIX_ENV=bench mix do es.reset, app.start, bench) to see how fast it runs. EventStore writes 4,000-8,000 events/sec and can read 26,000-27,000 events/sec on my laptop.

It’s not possible to replay events by aggregate type - it only supports by aggregate identity or all events - nor read a stream backwards. But you likely wouldn’t use an event store for this purpose. Instead you would project the events into a denormalised read model designed to support the querying needs of your administrators. You could even use an event handler to push the events to an external system, such as Elasticsearch, Logstash, and Kibana, in real-time purely for admin purposes.

Hope that helps you out.

slashdotdash

slashdotdash

I’m using GraphQL for a CQRS/ES Elixir app where mutations are mapped to commands and dispatched. I’m using Commanded, which has async eventually consistent handlers (e.g. read model), but it allows you to simulate strong consistency during command dispatch. This is the approach I currently use.

Another approach is to not return any data from your mutation, but instead use a subscription to have the server push data to the client after it has been updated. If you use Commanded’s Ecto projections library it provides an after_update callback function which would be the ideal integration point to push to an Absinthe subscription.

slashdotdash

slashdotdash

Sorry, too many questions on various different mediums to keep track of. No ETA on completing the book yet, I’m currently working on getting the next versions of Commanded and Event Store ready to publish.

slashdotdash

slashdotdash

I opted for the self publishing route as I considered the subject matter too niche for a technical publisher, and wanted the freedom to write at my own pace.

The book takes a step-by-step approach to building a REST API using CQRS and event sourcing for the core domain model.

I’m also considering writing a chapter on “live queries” whereby Phoenix channels are used to push read model updates down to the client, in response to published domain events. I’ve already built a working prototype in another, closed source, web app that can be extracted.

Where Next?

Popular in Books Top

AstonJ
https://www.packtpub.com/sites/default/files/3964_Elixir%20Cookbook_Cover_1.jpg
New
New
wintermeyer
At https://elixir-phoenix-ash.com I publish training material for Elixir and Phoenix. Text base tutorials which start at zero. Recently I...
New
meraj_enigma
New book from Packt publication that goes into teaching how to write a web framework using Elixir. About this book Elixir’s functional...
New
PragmaticBookshelf
This project based book gets you up to speed on building and deploying Elixir IoT applications using Nerves, as you develop a real-world ...
New
AstonJ
Classing this as a free online book :003: By Sean Callan with help from the community Lessons about the Elixir programming language...
New
AstonJ
Don’t forget you can get 35% off the ebook using the code ‘devtalk.com’ :023: Current: Search Original: Search For those looking for ...
New
PragmaticBookshelf
Svilen Gospodinov edited by Jacquelyn Carter @jkcarter Learn different ways of writing concurrent code in Elixir and increase your appli...
New
PragmaticBookshelf
Sean Moriarity @seanmor5 edited by Tammy Coron @Paradox927 From finance to artificial intelligence, genetic algorithms are a powerful t...
New
germsvel
:wave: Hi there, I’ve been working on a Test-Driven Development with Phoenix book. It teaches TDD and BDD by building a chat app from th...
New

Other popular topics Top

Tee
can someone please explain to me how Enum.reduce works with maps
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
273 38985 115
New

We're in Beta

About us Mission Statement