Can an aggregate be part of a domain-event?
Asked Answered
H

2

5

Consider an aggregate with many properties. For example UserGroup. If I want to publish a UserGroupCreatedEvent I can do 2 things:

  1. duplicate the properties from the just created UserGroup to UserGroupCreatedEvent and copy their values. OR:

  2. Refer to the new UserGroup within the UserGroupCreatedEvent

In many examples, like Axon's Contacts App, I've seen property duplication. I wonder why, and if in real-world CQRS applications, this is not a lot of overhead, and developers choose to refer the aggregate instead.

Histrionic answered 28/8, 2015 at 14:16 Comment(0)
S
5

An important property of domain events is that they are immutable. Bearing that in mind, the two possibilities you mention differ greatly:

  • Duplicating properties records their value at the time the UserGroup was created.
  • Referencing the UserGroup by ID just tells you that a UserGroup was created, but not the properties it had at the time. If the UserGroup has been deleted in the meantime, this means that the information is lost.

Which properties you copy depends on just that difference. Do you need to be able to look up e.g. the name of a UserGroup at its creation time? Add it as a property. If not (and if it's not expected that it ever will be required), don't.

Also, domain events have a global scope (i.e. they are meaningful outside of your BC), so you should include all information that clients outside of your BC need to make sense of the domain event.

Note that attaching the whole aggregate root object to a domain event violates the immutability rule of domain events, so this is most probably a bad idea.

Sortilege answered 28/8, 2015 at 14:57 Comment(3)
Thanks for this great insight, together with MikeSW's answer it makes totally sense to see the event as a minimal set of data required for consumers to deal with the event.Histrionic
On create time of the UserGroup it has a name, description, date, privacy setting, creator user (owner). I think the GroupStartedEvent should contain all this data in order to reproduce the state of the UserGroup (i.e. in case of event replay), isn't?Histrionic
@Pepster: yes, if the creator is not an entity. For the event to be immutable, all its members must be immutable, too. So if the creator is an entity, you should probably just put the creator ID in the event, not the whole user.Sortilege
W
6

An event is a DTO and it's meant to cross boundaries. Including the aggregate directly has the following problems:

  • The aggregate is a concept that makes sense only in its own bounded context;
  • An event should contain only the relevant changes, not the whole state of the concept;
  • Because an event is a DTO, at one point it will be (de)serialized and that would be a technical problem with properly encapsulated objects;
  • Every component/context receiving handling the event would have a dependency of the component where the aggregate is defined;

These are the main reasons why a Domain Event should be just a flattened representation of the relevant state changes.

P.S: If you need to include the whole state in your event, maybe the events is improperly designed or you're dealing with a simple data structure. Usually an aggregate contains some value objects and/or encapsulates some business constraints.

Walleye answered 28/8, 2015 at 14:58 Comment(0)
S
5

An important property of domain events is that they are immutable. Bearing that in mind, the two possibilities you mention differ greatly:

  • Duplicating properties records their value at the time the UserGroup was created.
  • Referencing the UserGroup by ID just tells you that a UserGroup was created, but not the properties it had at the time. If the UserGroup has been deleted in the meantime, this means that the information is lost.

Which properties you copy depends on just that difference. Do you need to be able to look up e.g. the name of a UserGroup at its creation time? Add it as a property. If not (and if it's not expected that it ever will be required), don't.

Also, domain events have a global scope (i.e. they are meaningful outside of your BC), so you should include all information that clients outside of your BC need to make sense of the domain event.

Note that attaching the whole aggregate root object to a domain event violates the immutability rule of domain events, so this is most probably a bad idea.

Sortilege answered 28/8, 2015 at 14:57 Comment(3)
Thanks for this great insight, together with MikeSW's answer it makes totally sense to see the event as a minimal set of data required for consumers to deal with the event.Histrionic
On create time of the UserGroup it has a name, description, date, privacy setting, creator user (owner). I think the GroupStartedEvent should contain all this data in order to reproduce the state of the UserGroup (i.e. in case of event replay), isn't?Histrionic
@Pepster: yes, if the creator is not an entity. For the event to be immutable, all its members must be immutable, too. So if the creator is an entity, you should probably just put the creator ID in the event, not the whole user.Sortilege

© 2022 - 2024 — McMap. All rights reserved.