kraades

kraades

DDD/CQRS/ES/NoSQL and functional programming

I was wondering if anyone is using Domain Driven Design and/or CQRS and/or Event Sourcing and/or NoSQL storage for a business application that is written in a functional language (in particular Elixir and/or Phoenix).

Hit or miss? I am getting some mixed signals. Any thoughts would be appreciated.

What is it?

Domain Driven Design

CQRS, Task Based UIs, Event Sourcing agh! - Greg Young
http://codebetter.com/gregyoung/2010/02/16/cqrs-task-based-uis-event-sourcing-agh/

CQRS - Martin Fowler

Event Sourcing - Martin Fowler

Some links…

Functional Data - Greg Young
Event Sourcing is “Functional Data Storage”

A Functional Foundation for CQRS/ES - Mathias Verreas

Domain Driven Design with the F# Type System - Scott Wlaschin

CQRS with Elixir and Phoenix - Jean-François Cloutier

Building a CQRS/ES web application in Elixir using Phoenix
Case study describing how I built a web app following a Command Query Responsibility Segregation and event sourcing pattern.

Most Liked

slashdotdash

slashdotdash

I’ve created an “awesome list” of Elixir and CQRS/ES resources: Awesome Elixir and CQRS.

The list is designed for only CQRS/ES resources that explicitly target Elixir/Erlang, as there’s an existing awesome collection of general domain-driven design content.

Contributions via pull request most welcome.

hubertlepicki

hubertlepicki

I am using CQRS in one project. So this is qorking, and I see no reason why it would not.

CQRS/DDD and friends are not bound to object oriented programming at all. Also, Elixir/Erlang are not that much different from object oriented languages when you think about it.

What I am doing at the moment is that I have two supervised workers, started when my application starts:

  • CQRS.Commands
  • CQRS.Events

there’s little bit of DSL in CQRS.Commands to define the list of commands my system accepts. These look like:

public MyApp.LogIn   
public MyApp.Register
private MyApp.CreatePost
private MyApp.DeletePost`

I have a single controller exposed on /api/commands that accepts params that have command name and payload. Public commands are ones that do not require User fetched (have plug for that). Private commands are the ones that get forwarded payload, but additionally current user.

Command looks like this inside:

defmodule MyApp.Commands.Register do
  alias MyApp.Repo
  alias MyApp.User
  alias MyApp.Events

  import  MyApp.Validator

  alias MyAppCommands.Register.Form

  def execute(params, _ \\ nil) do
    form = Form.from_params(params)

    if valid?(form) do
      Events.trigger("UserRegistered", event_data(form))

      {:ok, %{message: "email conrirmation needed"}}
    else
      {:error, errors(form)}
    end
  end

  defp event_data(form) do
    %{
      id: UUID.uuid4(),
      first_name: form.first_name,
      last_name: form.last_name,
      email: form.email,
      lang: form.lang,
      password_hash: Comeonin.Bcrypt.hashpwsalt(form.password),
      email_confirmation_token: Ecto.UUID.generate
    }
  end

  defp token_for_user(user) do
    Phoenix.Token.sign MyApp.Endpoint, "user_id", user.id
  end
end

and in my system commands can either succeed :ok , then generate some events, or fail (return tuple of :error and validation messages.

I do simple validations with GitHub - CargoSense/vex: Data Validation for Elixir · GitHub.

Generated events are being dispatched by my CQRS.Events, that is also a bit of DSL that lists all the events that can happen. They return nothing and they should succeed. I do not have the strategy worked out yet on what to do when they fail. I am experimenting here, not everything is yet perfect.

But basically, commands gets executed, generates some events, those events are handled by events handlers. This is all happening in two workers that are GenServers, so one thing at a time.

In addiion to that I package all my queries into MyApp.Queries… etc. Events modify data, queries read data, I have clear separation here.

Queries are executed normally in Phoenix controllers.

I use Phoenix’ views to serialize results of my queries and send over to client either via JSON or just embed the thing into conn and pass to view.

I haven’t figured everything out yet. I will wrap it up in a library, and write a blog post soon. Maybe it’ll be useful for someone and maybe I get some good feedback. I am not CQRS/ddd expert, so will need that.

sasajuric

sasajuric

Author of Elixir In Action

It’s certainly not intentional :slight_smile:
That said, I’ve read the Evans book a long time (~ 10 years) ago, so it’s possible that some ideas got stuck in my subconsciousness and are still present in my coding style :slight_smile:

Where Next?

Popular in Wikis Top

nicbet
Introduction Now that the language is picking up support and maturing nicely, I’d like to start a collection of common and recurring Elix...
New
Eiji
At start some definitions: HTTPS (is a protocol for secure communication over a computer network which is widely used on the Internet) -...
New
georgeguimaraes
Hi people, since the new year is coming, I’d like to plan my travels for events in 2017. So, what events (Elixir or FP related) that you...
New
OvermindDL1
It was stated at elixir-lang.org blocked in Russia · Issue #6172 · elixir-lang/elixir · GitHub that Mirrors of the primary Elixir website...
New
AstonJ
I’ve noticed we’ve got a few now - wonder if we can compile a list? This is a wiki - anyone at Trust Level 1 can edit :023: Link: http...
New
anildigital
Here is list of plugins for different editors Sublime Text 3 — Elixir.tmbundle - GitHub - elixir-editors/elixir-tmbundle: A TextMate a...
New
jdumont
Guide Using an iPad for web development can be easily split into two main parts: Setting up the iPad as a thin client Working in a remo...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 48342 226
New
BartOtten
A wiki for Doom Emacs Doom is a configuration framework for GNU Emacs. It focuses on performance and customizability. It can be a founda...
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...
274 41989 114
New

Other popular topics Top

vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
AstonJ
Please see the new poll here: Which code editor or IDE do you use? (Poll) (2022 Edition) It’s been a while since we first asked this, I...
208 31265 143
New
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 43487 311
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...
274 41989 114
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement