Question

I'm currently developing an application using reactive programming. Every entity creation or modification in the system publishes an event and no two entities can be created/modified within the same use case.

In this situation, there are entities that have to be created based on specific states of other entities. For example, there is an entity Slot that, when created with a state IN_AUCTION, should trigger the creation of an Auction entity. This is optional, as the Slot could be created with a state AVAILABLE, in which case, no Auction should be created.

Given this is the case, my doubt is about the type of event to publish when the Slot is created. These are the options I've thought about:

  1. Publish a generic SlotCreatedEvent. In this case, the listener would need to verify the state of the Slot, either by adding it to the Slot event or by querying it to check its state.
  2. Publish a SlotInAuctionEvent or a SlotAvailableEvent. In this case, there would be a specific listener that would create the Auction without checking the Slot state but if I follow this approach I could have an explosion of events.

So, given this example, what's the expected granularity when publishing events? Should there be a specific event for each state/entity modification or just a generic one with all the information of the entity modified?

Was it helpful?

Solution

In principle, I think what's most convenient for your event handlers should be a secondary concern. One of the major advantages of events is that the event source does not need to know anything about the consumers - so you don't know what their needs are.

The question really comes down to what constitutes an event conceptually. I would argue that creating an "in auction" slot and a "not in auction" slot are not separate events - otherwise, you end up with a separate event for every combination of parameters.

However, you'll also want to avoid flooding your consumers with unnecessary information. Furthermore, I think it's wise to avoid sending the same information in different events, if possible.

In your example, you risk duplicating the status information in the SlotCreated event and the SlotStatusUpdated event. If you had to react to a slot being 'available', you'd have to subscribe to two events.

A possible solution to this problem might be to publish two events when you create a slot: the SlotCreated event does not carry slot-status information, but you'll also immediately raise SlotStatusUpdated. Then AuctionCreator only has to subscribe to the latter. (If SlotCreated is of no interest to anyone, you could even skip this event).

Side Note: A module that only needs to react to new slots with a given status will have to do more work in this case. I'd argue that this is a natural reflection of the more complex condition. (If there are many such subscribers, you could have an intermediary that combines both events to a new event). In any case, there may be situations where this approach is not practical, but I do think it would usually be a relatively clean solution.

I think we can summarize the above considerations into the following rules of thumb:

  • If two events hold the same information, extract that into a new event

  • Don't create a new event just to suit a subscriber's needs

Unfortunately, this still leaves one question open: do we have a StatusChanged event or separate SlotOpenedForAuction, SlotReserved and SlotMadeAvailable events?

There might be a technical reason for choosing separate events: if you have a large number of subscribers, each of which only has to handle slots in a particular status, separate events are more efficient. (Raising an event is an O(n) operation). Otherwise, you should use the domain terminology as a guide - i.e. do users talk about a slot's 'status'?

Licensed under: CC-BY-SA with attribution
scroll top