- Reason about user intent, not updating data.
- Domain Events are the immutable source of truth
- Business language, userRegistered, depositedMoney
- State in the application is just a reflection of aggregated events
- Commands and Queries are separated (write and reads)
POST
API
GET
POST
API
GET
Aggregate
EventHandler
Read model
EventStore
Register for changes
Process / company policy
Command
Domain Event
Aggregate
Actor
Read Model
External
System
Process / company policy
Deposit money
Money deposited
Bank account
Account owner
Account-overview view
External
System
Command
Read Model
Aggregate
Domain Event
Actor
defmodule BankAccount do
def execute(%BankAccount{} = account, %DepositMoney{amount: amount}) do
%MoneyDeposited{
account_number: account.account_number,
amount: amount,
balance: account.balance + amount
}
end
def apply(%BankAccount{} = state, %MoneyDeposited{balance: balance}) do
%BankAccount{state | balance: balance}
end
end
Deposit money
Money deposited
Bank account
defmodule BankAccount do
def execute(%BankAccount{} = account, %WithdrawMoney{amount: amount}) do
if amount > account.balance do
return {:error, :can_not_overdraw_account}
end
%MoneyWithdrawn{
account_number: account.account_number,
amount: amount,
balance: balance - amount
}
end
def apply(%BankAccount{} = state, %MoneyWithdrawn{balance: balance}) do
%BankAccount{state | balance: balance}
end
end
Deposit money
Money deposited
Bank account
defmodule ThankyouEmailHandler do
def handle(%DepositedMoney{account_id: account_id, amount: amount}, _metadata) do
Email.sendThankyouEmail(account_id, amount)
:ok
end
end
External
System
if handler doesn't ack - the eventstore will send another event
defmodule CEOBonusHandler do
def handle(%MoneyInBonusAccount{} = bonus_account, %DepositedMoney{} = event) do
if (bonus_account.amount < 100_000 && bonus_account.account_id != event.account_id) do
%DepositMoney{
id: bonus_account.account_id
amount: event.amount / 100
}
end
end
end
Takes in an Event, sends out a command
Process / company policy
Process / company policy
Deposit money
Money deposited
Bank account
Account owner
Account-overview view
External
System
Command
Read Model
Aggregate
Domain Event
Actor
Thank you Email