Hi,
I work in the trading domain and after a year in development I've made the following observation:
Most of our domain events are very similar to serialized imperative method calls, i.e :
{"event": "OrderFilled", "quantity" : 1, "price": 2, "orderId": "abc" }
which would have a matching applyOrderFilled(orderId, quantity, price) method in the relevant AG.
Three subsequent order fills would look like:
{"event": "OrderFilled", "quantity" : 1, "price": 2, "orderId": "abc" }
{"event": "OrderFilled", "quantity" : 1, "price": 1, "orderId": "abc" }
{"event": "OrderFilled", "quantity" : 1, "price": 3, "orderId": "abc" }
Which would aggregate to an order with "filledQuantity" : 3.
For the sake of this discussion I could have modelled the same events declaratively as :
{"event": "OrderFilled", "quantity" : 1, "price": 2, "orderId": "abc" }
{"event": "OrderFilled", "quantity" : 2, "price": 1.5, "orderId": "abc" }
{"event": "OrderFilled", "quantity" : 3, "price": 2, "orderId": "abc" }
Which would also result in the same "filledQuantity" : 3.
We have a use case in which we apply corporate actions such as splits and dividend distribution which trigger more declarative style domain events in our "Trading" bounded context, such as :
{"event": "OrderAdjusted", "quantity" : 1.5, "price": 4}
The corporate actions processing is done by a different app in a different bounded context, therefore the "Trading" bounded context really shouldn't care for the mechanics (i.e type of corporate action)
My question is more general : What are the use cases and potential tradeoffs of using a more declarative style of events instead of imperative ones?
Best regards,
Erik.