2

Is it preferable to define a single 'container event' like below:

trait UserStatus
case object Active extends UserStatus
case object Inactive extends UserStatus

case class UserStatusChanged(newStatus: UserStatus, userId: String, eventTime: Long)

or define to multiple events:

case class UserBecameActive(userId: String, eventTime: Long)
case class UserBecameInactive(userId: String, eventTime: Long)

The first approach seems more maintainable by requiring less boilerplate to support additional user statuses, but the second seems more in the spirit of DDD and closer to the examples I've seen.

  • One could achieve both using polymorphism. E.g. UserBecameAcitve inherits from UserStatusChanged – king-side-slide Nov 19 '18 at 20:39
0

Whether you go the first or the second way depends entirely on your needs. If you are only ever interested about the situation when a user becomes active and couldn't care less about them becoming inactive, defining only the UserBecameActive event and dispatching it to your system when a user is activated would be the recommended way to go. After all, why define the UserStatusChanged for all status types if you will only ever react to this even when the value of the newStatus property is in fact Active? That's just another if/else in your code. Thanks to this you can then define event handlers reacting to this event type and perform additional logic when such even occurs within your system, without the need to inspect the potential UserStatusChanged values to know whether the user is active or not. Not to mention, UserBecameActive probably fits way better in your ubiquitous language than the UserStatusChanged event.

On the other hand, having too granular approach won't most likely solve all your problems either. If you start introducing many event types for each property (or a thing of significance) of an entity, you will most likely come across a situation where you could use having multiple attributes of the event but then the event wouldn't play nicely in your domain. So then perhaps event having just a simple UserHasBeenUpdated event could be perfectly reasonable.

0

There are two possible definitions of events here and they should be treated differently. If you’re talking about a DDD event within a domain, I would go with the two distinct events. Domain Events should indicate something significant is happening and needs to be addressed. There’s an expectation that something within the domain will handle that event appropriately. When you create a Domain Event, you should have a handler specifically in mind. Note that this means if there's code that needs to handle any state change regardless of new value you would also need the UserStatusChanged.

If you are talking about what events to store in an Event Store, I would go with the generic UserStatusChanged. These events should not incorporate domain logic, they only reflect state changes in your domain. If you limit to UserBecameActive and UserBecameInactive you are implying those are the only two states that are significant. I understand those are probably the only two states that exist at the moment, but what happens when a third is added (such as “Membership Pending”). Do you now add a third event? What about the code that doesn’t care what the UserStatus value is, just that it changed (caching algorithms come to mind)? For Event Store Events, you do not need to have a specific handler in mind.

Event store events should say “something changed” not “something changed to an important value”. That’s up to the domain to decide.

Domain events should say "something significant is happening" regardless of whether that involves a state change or not.

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.