ayeo
ayeo

Reputation: 482

Aggregate Root including tremendous number of children

I wonder how to model Calendar using DDD and CQRS. My problem consist in increasing number of events. I consider Calendar as Aggregate Root which contains Events (Calendar Events). I dont want to use ReadSide in my Commands but I need way to check events collisions at domain level.

Upvotes: 1

Views: 729

Answers (2)

VoiceOfUnreason
VoiceOfUnreason

Reputation: 57194

I wonder how to model Calendar using DDD and CQRS. My problem consist in increasing number of events.

The most common answer to "long lived" aggregates is to break that lifetime into episodes. An example of this would be the temporary accounts that an accountant will close at the end of the fiscal year.

In your specific case, probably not "the Calendar" so much as "the February calendar", the "the March calendar", and so on, at whatever grain is appropriate in your domain.

Im not sure if Im right about DDD aproach in terms of validation. I believe the point is not to allow the model to enter into invalid state

Yes, but invalid state is a tricky thing to define. Udi Dahan offered this observation

A microsecond difference in timing shouldn’t make a difference to core business behaviors.

More succinctly, processing command A followed by processing command B produces a valid state, then it should also be true that you end up processing command B first, and then A.

Let's choose your "event collisions" example. Suppose we handle two commands scheduleMeeting(A) and scheduleMeeting(B), and the domain model understands that A and B collide. Riddle: how do we make sure the calendar stays in a valid state?

Without loss of generality, we can flip a coin to decide which command arrives first. My coin came up tails, so command B arrives first.

on scheduleMeeting(B):
    publish MeetingScheduled(B)

Now the command for meeting A arrives. If your valid calendars do not permit conflicts, then your implementation needs to look something like

on scheduleMeeting(A):
    throw DomainException(A conflicts with B)

On the other hand, if you embrace the idea that the commands arrive shouldn't influence the outcome, then you need to consider another approach. Perhaps

on scheduleMeeting(A)
    publish MeetingScheduled(A)
    publish ConflictDetected(A,B)

That is, the Calendar aggregate is modeled to track not only the scheduled events, but also the conflicts that have arisen.

See also: aggregates and RFC 2119

Upvotes: 4

Constantin Galbenu
Constantin Galbenu

Reputation: 17673

Event could also an be an Aggregate root. I don't know your business constraint but I think that if two Events colide you could notify the user somehow to take manual actions. Otherwise, if you really really need them not to colide you could use snapshots to speed up the enormous Calendar AR.

I dont want to use ReadSide in my Commands but I need way to check events collisions at domain level.

You cannot query the read model inside the aggregate command handler. For the colision detection I whould create a special DetectColisionSaga that subscribes to the EventScheduled event and that whould check (possible async if are many Events) if a colision had occurred and notify the user somehow.

Upvotes: 3

Related Questions