6

Imagine that I am creating and Ecommerce application. For sake of simplicity, I will describe only 3 bounded contexts.

  1. Product Catalog: it's responsible for maintain product descriptions, characteristics and so on
  2. Pricing: it's responsible for products pricing
  3. Inventory: it's responsible for inventory management. If a product is in stock or not.

So when a customer just enter the Ecommerce site, I would like to show the products. For that I need to have the price and still needs to know that if we have the product in stock.

So what's is the best way to do that?

  1. First approach is the Product Catalog just make synchronous requests to Inventory and Pricing.
  2. Second approach is to maintain the price information and if the product has in stock on the Product Catalog BC. So every time a price is changed in Pricing Context it will raise and event and the Product Catalog can update this information. The same way for Inventory context.

I prefer the second approach, but it seems that I am replicating information e.g price and stock.

Thoughts?

3
  • Option 1. It has the best use of Single Source of Truth. Commented Apr 2, 2018 at 15:10
  • 1
    Why is pricing a separate context? I can understand inventory being separate, but price has been an attribute of product in every system I've seen.
    – Dan Wilson
    Commented Oct 1, 2018 at 18:19
  • 7
    @DanWilson, because pricing can be complicated. It can be dynamic, it can depend on BBD, rate of sale, volume discounts, promotions, the age of the stock, ulterior discounts from the supplier, promised discounts from supplier on volume sold, business policy, etc. Commented Nov 22, 2018 at 15:40

4 Answers 4

4

I would try to avoid both scenarios: one BC doing synchronous requests to the other and polluting the data of one BC with data from the other.

You have two main options:

  1. Keep a presentation read model with the data ready to display (likely a single denormalized table, for best performance).
  2. Use a composite UI. The UI makes several calls to construct the whole page (catalog, prices, stock, promotions, etc).

Also, you should consider the "search" feature. Eventually, if you have a very large catalogue, you'd likely have a complex way to search for products. This means that you'll need all searchable data (products with stock, products with a certain price range, etc.) in a search index. Depending on how you build this search system, it could work as a full read model (the result of the search contains all information required to construct the page) or you'll end up with a composite UI (the search result needs to be enriched by doing calls to several BCs.

As a final note, the UI composition can be done in 2 places: from the client directly, or creating a dedicated API that calls the other BCs and constructs a DTO for the given page. This second option might perform better if you avoid several remote calls, but might require a different implementation for each client (mobile, web, desktop) as each client page might have different needs.

3
  • The problem with the second option is that it's almost impossible. Imagine that I have 1000 products. For show the product catalog I will need to make many round trips..(inventory+pricing+and so on). Commented Apr 2, 2018 at 12:44
  • 1
    Yes, the composite UI works for the product details page. You do separate calls to load the product description, images, reviews, Q&A, related products, etc. Regarding the 1000 products, well, you are not going to show them all at once, but you'll still have to load pages of 10 to 50 products. Note my comment about the search. Because not only you have to show this products. You'll need to be able to search them and sort them by different criteria (category and price range are from different BCs). So, your best option is the denormalized read table (or maybe search index, like Elastic search) Commented Apr 2, 2018 at 19:38
  • I believe this should be the proper answer to this question. Here's more about the composite UI tigerteam.dk/2015/… Commented May 30, 2019 at 20:06
3

I would definitely try to avoid Option #1. Synchronous dependencies between services are an anti-pattern and just complicate operations.

Replicating information is not a bad thing in itself, when there is a clear producer and consumers. Although it should be kept low as possible, I would have no problem having data replicated.

The point is, when other services might be down or overloaded, the product page would still work. This is a good thing you probably want for an e-commerce site.

The downside is, that the information on that page could be somewhat out-of-date. That is normally not a problem, since you will see the exact information when you switch from "browsing" to actual checkout, which should be another application with the "master" data.

Of course there is always the third option, to try to re-arrange the service boundaries in a way which does not require that much data to be replicated.

1
  • Duplicating data would be complex when pricing service has complex business logic. Imagine implementing HappyHours scenario (price is discounted between 8pm till 10pm). Simple events won't work in this case, and there has to be some background job (or similar) that will update the prices at 8pm and then again at 10pm. On top of that, there can be more complex cases, e.g. different price based in User tier or discount policy. Commented Feb 20, 2021 at 20:12
0

I don't like 2. I'm against price changes needing to propagate into the product description. I'd rather have price, availability, and description looked up every time someone wanted a report on a product. That report will draw upon all three bounded contexts, get time stamped, and will never be updated. It will be replaced when requested again.

2
  • I am ok with this solution, just on the product page (where the customer see more details about the product). But, for the showcase it's impossible. So many round trips to the backend... Commented Apr 2, 2018 at 12:45
  • 1
    Help me see the problem. I just see three queries. Commented Apr 2, 2018 at 13:30
0

You have another domain: the Website or the Mobile Application, namely the Presentation. This can act like a Bounded context, with its own read models, that are based on the models from the other bounded context. It has no write-side business rules to protect.

The Presentation keeps acts like a local cache, an integration layer. If your system is event-based then you can use the events to keep it up-to-date.

So whats is the best way to do that? 1.On approach is the Product Catalog just make synchronous requests to Inventory and Pricing. 2. Second approach is to maintain the price information and if the product has in stock on the Product Catalog BC

Try to keep the 3 bounded context clean, they should have independent models, so don't mix them.

One other way of integrating them is when a customer is placing an order. In that process all 3 bounded contexts are used but they do not know of each other, you use a Process manager/Saga to manage the long running process. This is an integration for the write/command side of your system.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.