Entities,
Aggregates,
and Events
What is Entity?
What is Aggregate?
Entities
vs
Aggregates
Entity
- Has ID
- Not accessible from outside of Aggregate it belongs to
- i.e. individual Transactions for Bank Account
Aggregate
- Has aggregate root
- Hides underlying Entities from direct modification
- i.e. Bank Account and it's Transactions
Applying Event
on Aggregate
BankAccount::Created.call
BankAccount::Approved.call
BankAccount::Blocked.call
BankAccount::Destroyed.call
BankAccount::TransactionsImported.call
BankAccount::WithdrawalSuccessful.call
"Updated" trap
a.k.a. update everything!
def WWW
# [...]
BankAccount::Updated.call bank_account_id: id
end
def XXX
# [...]
BankAccount::Updated.call bank_account_id: id
end
def YYY
# [...]
BankAccount::Updated.call bank_account_id: id
end
def ZZZ
# [...]
BankAccount::Updated.call bank_account_id: id
end
def create_bank_account
# [...]
BankAccount::Updated.call bank_account_id: id
end
def approve_bank_account
# [...]
BankAccount::Updated.call bank_account_id: id
end
def import_transactions
# [...]
BankAccount::Updated.call bank_account_id: id
end
def destroy_bank_account
# [...]
BankAccount::Updated.call bank_account_id: id
end
def create_bank_account
# [...]
BankAccount::Created.call bank_account_id: id, organization_id: id, [...]
end
def approve_bank_account
# [...]
BankAccount::Approved.call bank_account_id: id
end
def import_transactions
# [...]
BankAccount::TransactionsReplaced.call bank_account_id: id,
transactions: [...]
end
def destroy_bank_account
# [...]
BankAccount::Destroyed.call bank_account_id: id
end
Rule of
Reversible EventĀ
class BankAccount
class Created
def self.call(bank_account_id: id, organization_id: id, [...])
# [...]
end
end
class Approved
def self.call(bank_account_id: id)
# [...]
end
end
class TransactionsReplaced
def self.call(bank_account_id: id, transactions: [...])
# [...]
end
end
class Destroyed
def self.call(bank_account_id: id)
# [...]
end
end
end
Enriching Events
a.k.a. "but someone need this in payload"
BankAccount::Approved.call bank_account_id: id, transactions: [...]
BankAccount::Approved.call bank_account_id: id
class BankAccount::ApprovedHandler
def call(bank_account_id:)
transactions = TransactionsQuery.for_bank_account bank_account_id
Enriched::BankAccount::Approved.call bank_account_id: bank_account_id,
transactions: transactions
end
end
"Succeeded"
Entities, Aggregates, and Events
By Bernard Potocki
Entities, Aggregates, and Events
- 988