The typical example, the e-commerce system.
Let's say the Order
is in the Sales bounded context. Every Order
contains many OrderLine
, which stores the ProductId
.
The Product
is in the Product Catalog bounded context. Every Product
has its own ProductId
.
I understand that the ProductId
in Product Catalog bounded context could be different from the ProductId
in Sales bounded context.
If I want to delete a Product
, does it affect the Order
?
Later, I add a new bounded context, like Sales Reporting bounded context. It will use the Order
information and also the ProductId
to generate the report. In this case, how to keep the data consistent?
2 Answers 2
The question touches on two distinct but complementary aspects:
- the domain with domain models within bounded contexts. Several strategies are possible for context mapping, i.e. relating different models corresponding across the boundaries of each context.
- the architecture and the components that implement the domain models.
We could perfectly imagine different bounded contexts that end up being implemented in the same database. Moreover some parts of the bounded contexts could be aligned (e.g. Product
could be part of a shared kernel, or Sales
could be a conformist to Catalogue
slavishly taking over its Product
definition). In this case you wouldn't have a question.
But the bounded contexts could as well have a very different view on products, such as having different product ids and even different lifecycles as you described. Typically, an anticorruption layer in one domain could bridge the gaps between the different product worlds. If you'd still have an implementation in the same database, the anticoruption layer would probably contain a mapping table (e.g. SalesProductId + CatalogueProductId + status information to deal with the different lifecycles or some redundant data, that would stay if the catalogue product is deleted).
Finally, you could have a very different architecture, e.g. microservices per bounded context, with independent databases. This deployment perspective is orthogonal to the context design: you could still have a shared kernel or conformist, in which case you'd need to replicate some data across the services. Or you could manage domain specific products in each microservice, with an anticorruption layer for making the glue and enabling synchronisations between divergent models. The additional logic for synchronising the data is independent of the context boundaries; it's just that these would coincide with the boundaries between microservices. Typically, such synchronization would base itself on events (domain events, that can be translated by the anticorruption layer)
DDD is mostly used together with an event driven architecture. The communication between the Product Catalog and the Sales Bounded context would be done by using events.
This would mean that in your scenario, the services within the sales bounded context would be notified of the deletion by an event. How the sales domain copes with the deletion of a product (cancel orders, disallow any new order to contain the product) is not an architectural question, but should be worked on with domain experts.
On how to deal with events I would suggest to read up on event driven architecture and more precisely event sourcing.
The same goes for a new domain added to your application. A new reporting domain can read past events, so it will know about when a product existed and when it was deleted and react accordingly. The same goes for orders.
-
Thank you for your answer. I know that domain experts are very important in DDD, but in this question, I want to keep everything simple. Let's say the
Order
will be kept for 10 years, no matter theProduct
is still sold or not. In that case, how do you solve this problem?Ngọc Nguyễn– Ngọc Nguyễn11/23/2021 12:17:59Commented Nov 23, 2021 at 12:17 -
1One way this is done in practice is to hold a copy of the domain object in a datastore. So if a product is created and a
ProductCreated
event is sent, you would store a copy of the product in the Sales service. On aProductUpdated
event you'd update the product and on aProductDeleted
event you'd set a flag, that it has been deleted. So you keep the reference, but you are still decoupled from the Product Catalog domain.minime– minime11/23/2021 14:55:39Commented Nov 23, 2021 at 14:55
Explore related questions
See similar questions with these tags.
product
has been purchased successfully. Then after a time, the store decides not to sell it anymore and delete the product. This behavior will affect every data in the past thatproduct
involved. I am trying to solve this problem.