devoured elysium
devoured elysium

Reputation: 105227

Is it a good idea to rely on a given aggregate's history with Event Sourcing?

I'm currently dealing with a situation in which I need to make a decision based on whether it's the first time my aggregate got into a situation (an Order was bought).

I can solve this problem in two ways:

  1. Introduce in my aggregate a field stating whether an order has ever been bought (or maybe the number of bought orders);
  2. Look up in the aggregate's history for any OrderWasBought event.

Is option 2 ever acceptable? For some reason I think option 1) is for the general case safer / cleaner but I lack experience in these matters.

Thanks

Upvotes: 1

Views: 100

Answers (2)

MikeSW
MikeSW

Reputation: 16378

Option 2 is valid as long as the use case doesn't need the previous state of the aggregate. Replaying events only restores a readonly state, if the current command doesn't care about it, searching for a certain event may be a valid simple solution.

If you feat "breaking encapsulation" this concern may not apply. Event sourcing and aggregate are concepts mainly they don't impose a certain OO approach. The Event Store contains the business state expressed as a stream of events. You can read it and use it as an immutable collection any time. I would replay events only if I'd need a certain complex state restored. But in your case here, the simpler 'has event' solution encapsulated as a service should work very well.

That being said, there's nothing wrong with always replaying events to restore state and have that field. It's a matter of style mostly, choose between a consistent style of doing things or adapt it to go for the simplest solution for a given case.

Upvotes: 0

Golo Roden
Golo Roden

Reputation: 150902

IMHO both effectively do the same thing: The field stating that an order was bought needs to be hydrated somehow. Basically this would be done as part of the replay, which basically does not mean anything but that when an OrderWasBought event happened, the field will be set.

So, it does not make any difference if you look at the field, or if you look for the existence of the event. At least it does not make a difference, when it is about the effective result.

Talking about efficiency, it may be the better idea to use a field, since this way the field gets hydrated as part of the replay, which needs to be run anyway. So, you don't have to search the list of events again, but you can simply look at the (cached) value in the field.

So, in the end, to cut a long story short: It doesn't matter. Use what feels better to you. If the history of an aggregate gets lengthy, you may be better off using the field approach in terms of performance.

PS: Of course, this depends on the implementation of how aggregates are being loaded – is the aggregate able to access its own event history at all? If not, setting a field while the aggregate is being replayed is your only option, anyway. Please note that the aggregate does not (and should not!) have access to the underlying repository, so it can not load its history on its own.

Upvotes: 3

Related Questions