Search code examples
.netalgorithmmicroservices

How do I sort hundreds of products by price when price is calculated at the time the request is made


Given the following three services:

  1. Product Service: stores product information
  2. Availability Service: determines the availability of the products stored in the product service using a schedule optimisation algorithm
  3. Price Service: stores rules for pricing a product as well as discounting the prices

Composing all these together is a BFF service which coordinates all requests that need to be made in order to provide the customer with the information on which products match their criteria, and are available, and at what price. The number of products will be in the hundreds, perhaps even thousands over time. Each request returns a page of the products (lets say 10 out of 100s).

When a customer searches for products, the BFF service is called which in turn calls the three services in the order listed.

Problem Sorting is required on the products. The first requirement is by price. Price is: 1. Stored in a different service 2. Is determined using various algorithms (could even be a dynamically determined price i.e. "personalised" price)

Question How do we sort based on price? I have some ideas on some not so good solutions. But looking for more input from others who may have solved this problem. Booking.com does something similar...


Solution

  • I understand you'd like to show consistent data with almost real time accuracy. I'd consider following options:

    1. Rethink your micro services composition. Maybe in current design they are too small. Though all micro services you've mentioned are tightly coupled with a product entity. But of course it depends on many factors which i'm not going to cover here and i don't know your system enough to make such recommendation.

    2. Merge all three sources in BFF service. Sorting / paging could be applied on top of merged values. Raw merged result could be cached to avoid constant API round trips for each page. I guess prices will not change that often therefore it might be a viable and simple solution.

      Even if number of products is few thousand in-memory cache should be good enough to handle that.

    3. Build a dedicated model for reading (in other words duplicate the data). If BFF is responsible for providing read model then it could listen on domain events like "price changed", "product added", "product removed" and build its own async read model. That would allow to build pagable view using single DB query.

      You could also combine 2 + 3 and make the cache mechanism aware of domain events. Certain events could either invalidate entire cache or part of it (e.g. single product).

    4. I assume your micro services have their own dedicated database. You could expose a cross-db view providing desired functionality in single db query. Evangelists of microservices would say that this is an evil anti-pattern. Well, it is, but if you know what you're doing that might be a pragmatic option and I wouldn't cross it out.

    Each of options I mentioned comes with pros and cons. It would be hard to judge which would be best for you without wider knowledge about your ecosystem.