cqrs - Domain logic in command handler or event handler? -


i using cqrs , ddd build application.

i have account entity, transaction entity , transactionline entity. transaction contains multiple transactionlines. each transactionline has amount , points account.

if user adds transactionline in transaction has transactionline points same account 1 new transactionline, want add new transactionline amount existing one, preventing transaction having 2 transactionlines point same account.

ex :

before command :     transaction         transactionline1(amount=100, account=2)         transactionline2(amount=50, account=1)  command :     addnewtransaction(amount=25, account=1)  desired result :     transaction         transactionline1(amount=100, account=2)         transactionline2(amount=75, account=1) // add amount (50+25) instead of 2 different transactionlines  instead of  transaction     transactionline1(amount=100, account=2)     transactionline2(amount=50, account=1)     transactionline3(amount=25, account=1) // error, 2 different transactionlines point same account 

but wonder if best handle in command or event handler.

if case handled command handler

before command :     transaction         transactionline1(amount=100, account=2)         transactionline2(amount=50, account=1)  command :     addnewtransaction(amount=25, account=1)  // detects case  dispatches event     transactionlineamountchanged(transactionline=2, amount=75) 
  1. addtransactionline command received

  2. check if transactionline exists in new transactionline's transaction same account

  3. if so, emit transactionamountchangedevt event

  4. otherwise, emit transactionaddedevt event

  5. corresponding event handler handles right event

if case handled event handler

before command :     transaction         transactionline1(amount=100, account=2)         transactionline2(amount=50, account=1)  command :     addnewtransaction(amount=25, account=1)  dispatches event     transactionlineadded(transactionline=3, amount=25)  handler  // detects case     transactionline2.amount = 75  
  1. addtransactionline command received

  2. transactionlineadded event dispatched

  3. transactionlineadded handled

  4. check if added transaction's transactionline points same account existing transactionline in account

  5. if so, add amount of new transactionline existing transactionline

  6. otherwise, add new transactionline

neither commands nor events should contain domain logic, domain should contain domain logic. in domain, aggregate roots represent transaction boundaries (not transaction entities, transactions logic). handling logic within commands or events bypass boundaries , make system brittle.

the right place logic transaction entity.

so best way be

addtransactioncommand finds correct transaction entity , calls transaction.addline(...), logic , publishes events of happened transactionlineaddedevent or transactionlinechangedevent depending on happened. 

Comments

Popular posts from this blog

javascript - Chart.js (Radar Chart) different scaleLineColor for each scaleLine -

apache - Error with PHP mail(): Multiple or malformed newlines found in additional_header -

java - Android – MapFragment overlay button shadow, just like MyLocation button -