I will describe my problem with a very typical example, an e-commerce application.
Says we have to manage Products
, and we have 2 bounded contexts Sales
, and Warehouse
that store the product information.
The Sales
bounded context cares about price, product name, description.
The Warehouse
bounded context cares about sizes, position, quantity, quality.
When we create a new product, we have to input all of the above information. Following the CQRS pattern, we have to send 2 commands Create Product
to Sales
and Warehouse
bounded context, which could be 2 microservices.
The problem is, if the Product
is created in Sales
, but not valid to be created in Warehouse
, or the command to Warehouse
is not sent, then the Product
in Sales
does not make sense. The same goes with the reverse.
So how do you create an object, in this case, a product, that appears in multiple bounded contexts?
1 Answer 1
Product
objects in two different bounded contexts should be usually seen as two different objects which share the same name "just by coincidence". Of course, this is not completely coincidentally, since both objects will be a representation of the same physical item, but those two Product
classes can (and will) represent very different aspects of a real-world "product". This may go as far as storing products in the warehouse by their quantity (one Product
object represents multiple real-world items, counted by quantity), and storing products in Sales
in a 1:1 manner to their real-world pendant.
So in each bounded context, there is a creation process for its own Product
objects, implemented in some kind of Product
factory. These processes should be completely independent from the other bounded context.
Now let's assume, for example, there is a use case "Advertise Product" from Sales
, which checks if the product is available in the warehouse, and only creates the sales-related Product
object when there is still a corresponding product in the warehouse. Then in the context of this use case, the related Product
factory from Sales
has to query Warehouse
whether there are products of the give type in stock (this query may utilize a tempory warehouse Product
object, which should be created by the Sales
independent creation process). If the query to Warehouse
fails, "Advertise Product" won't deliver any saled Products
.
Same could work the other way round: say there is a use case "reorder products" from Warehouse
, and for determining the reorder quantity, Warehouse
needs to ask Sales
how many advance bookings for a certain product are already there. Then the creation process of "reorder products" will issue a query for the related products from Sales
. In case there will be nothing returned, "reorder products" won't create any warehouse Products
for reordering, or maybe just fewer ones.
So in short:
see
Warehouse.Product
andSales.Product
as different products, which can be created independently - hence the create commands should stay independentthere may be certain use cases which forbid independend creation of a product object on one context if it is not available in the other - if so, model and implement those use cases, for example, as a service, but don't try to stuff a whole use case implementation into a single creation command.
-
Base on your answer, I can see the
Warehouse.Product
andSales.Product
are different. TheProduct
add toSales
goes into a catalog. TheProduct
add toWarehouse
is the physical product, if I get it right. When the user queries for theSales.Product
to buy, does theSales
have to check theProduct
in theWarehouse
? If this happens, every query theSales
needs to update the information ofProduct
inWarehouse
. Is this true? Is there any better practice?Ngọc Nguyễn– Ngọc Nguyễn12/17/2021 08:01:53Commented Dec 17, 2021 at 8:01 -
"The Product add to Warehouse is the physical product,"- no, both product objects are just a model, implemented in the bits and bytes of your computers. The physical product is what UPS delivers to your home.Doc Brown– Doc Brown12/17/2021 09:44:25Commented Dec 17, 2021 at 9:44
-
"When the user queries for the Sales.Product to buy, does the Sales have to check the Product in the Warehouse?" - maybe, that depends totally on how you design your system and your use cases, and how you distribute the information between different parts of the system. Amazon, for examples, can offer you products and prices on their web site even if those products are out of stock (and they show you that information before you buy anything). So in case there is a "Sales" and a "Warehouse" microservice behind that (which I don't know), ...Doc Brown– Doc Brown12/17/2021 09:48:09Commented Dec 17, 2021 at 9:48
-
.. I guess "Sales" would have to query "Warehouse" for this kind of use case, that's quite normal. But that does not imply that every query for a product in "Sales" would require also a query to "Warehouse", I have no idea why you come to this conclusion.Doc Brown– Doc Brown12/17/2021 09:50:33Commented Dec 17, 2021 at 9:50
Explore related questions
See similar questions with these tags.