microservicesdomain-driven-designbounded-contexts

Is it recommended for a Bounded Context to communicate with another to validate entity relationships in Domain-Driven Design (DDD)?


I am developing an application using Domain-Driven Design (DDD), and I have defined two Bounded Contexts: "Catalog" and "PriceManagement."

In the "Catalog" Bounded Context, I have the "Article" entity, and in "PriceManagement," I have the "PriceList" entity. Each "PriceList" is associated with a specific "Catalog" and contains a list of Articles that belong to the same Catalog associated with the list.

My concern is how to validate this relationship between Articles and PriceLists to ensure that an Article added to a PriceList belongs to the same Catalog associated with that List.

Is it recommended for the "PriceManagement" Bounded Context to communicate with the "Catalog" Bounded Context to verify this relationship?

Alternatively, would it be more appropriate to replicate relevant Catalog information, such as the associated Articles, in the "PriceManagement" Bounded Context to avoid cross-context queries and simplify the validation?

What would be the best practice to perform this validation within the context of DDD?

I would greatly appreciate any advice, guidance, or experiences related to communication between Bounded Contexts, how to validate entity relationships, and whether it is suitable to replicate Catalog information in the Price Management Bounded Context within a DDD-based design.


Solution

  • In DDD it is best to not query across bounded contexts.

    Let's imagine if the article has other details like, say, the author's profile picture. What does that picture have to do with price lists? Nothing. You've now polluted your calling context.

    Now, assume you can make a query that filters out irrelevant detail. You've fixed the calling BC, but you could have a different problem. You now need to use repos for both BCs. Worse, if your BCs are in separate DB instances, you now are coupled to both of them.

    To fix both of these issues you can use domain events. In your Catalog BC, raise an event, say ArticleAdded, and only provide the details necessary for the PriceManagement BC: article name or ID, catalog name or ID, and anything else relevant. Your other BC can handle the event and update the correct PriceList.

    In this way your BCs are decoupled and you're still free to implement the repository layer however you want.

    There's a bonus. You could possibly eliminate the validation because only the correct price list will be updated in the first place! But, assuming you still need the validation for whatever reason, you can now add a Validate method on your PriceList aggregate, and that method does not have to query the Catalog BC. It doesn't even have to query the PriceManagement BC because your aggregate is presumably loaded with its article objects.

    And, one more thing: what are the article objects? Well, they are not Articles. They can't be. Those belong to the Catalog BC. Instead, the objects are value objects representing a projection of the Article into the PriceManagement BC.

    This projection (or view if you will) strips out extraneous detail such as that author pic. You could call that object Article if you wish. I personally prefer something that conveys the relationship. That can be specific like PricedArticle or something a little more general like ArticleReference or ArticleInfo.