architecturedomain-driven-designcqrsdddd

Alternatives to many-to-many relationships with CQRS


How do we model classic many-to-many relationships with CQRS/DDD?

I know that both DDD and CQRS implementations and solutions tend to be domain-specific, so it may be difficult to come up with a general answer to this question.

However, let's assume we have the familiar relationship between Book and Author. This is a classic many-to-many relationship.

To me, it seems most natural that Book and Author are two different Entities that each belong in their own Aggregate Root. Thus, explicitly modeling the many-to-many relationship between them is not the way to go.

How do we model an AddBookCommand? We want to be able to add a book to our library, and also somehow state that a particular Author wrote this Book. How do we model (and persist) such a relationship?

Neither Book nor Author seem like good candidates for Value Objects...


Solution

  • Supposing that both are aggregates, copy whatever author data you need into the Book aggregate upon adding the new book so that any subsequent commands have enough author data to work with. Now if the Author aggregate needs information about the books written by the author, then it could "subscribe" to the NewBookAdded event (technically you could send a RegisterAsAuthorOfBook command to the Author aggregate as a result of the NewBookAdded event). I presume one could model this the other way around as well, but I'm not that intimate with the Book Author domain.

    Bottom line is that you don't really store many-to-many because they don't scale. You have to start thinking of them (aggregates) as sending messages to each other. The bigger question is what needs to be consistent and at what point in time does it need to be consistent. Do we care that the Author does not instantaneously reflect the fact a new Book has been added, of which she/he's the author? Are there any invariants that Author wants to enforce with regard to the books he/she has written (and vice versa)?

    Another thing is to stop being data oriented and more behavior oriented. What's the behavior of the Book and Author aggregate? This will tell what data is required at which point and how it should be modelled.

    http://pastie.org/1220582 for a first stab at the Book aggregate.