Simplified DDD in Elixir

The discussion in Must RFC - Event Sourcing, simplified? reminded me that I wrote down some ideas about a simplified DDD-inspired architecture recently, and I decided to publish them now. As the post says, the ideas are rough and unproven, but maybe someone finds something useful in there.

5 Likes

Interesting! I can see how

In the past, I have settled on using embedded schemas for everything except projections, which need regular schemas. Commands, events, aggregates, handlers, etc would all have embedded schemas so that readers wouldn’t have to understand structs vs schemas. That’s one less decision a developer has to make when adding new features.

Changesets are defined in each command, but not for aggregates. However, I would return a changeset when rejecting a command in an aggregate. This approach allows for validation before dispatching the command, which works nicely with LiveView.

def execute(%__MODULE__{status: nil}, %StartSession{} = command) do
  [
    %SessionStarted{
      session_id: command.session_id,
      name: command.name
    }
  ]
end

def execute(%__MODULE__{}, %StartSession{}) do
  {:error,
    %__MODULE__{}
    |> Changeset.change()
    |> Changeset.add_error(:session_id, "has already started")}
end

It’s cool to see different approaches to working with ES code. Thanks for sharing.

2 Likes