Let's say you have two microservices (contrived example):

  1. Customers service
  2. Dashboard service

In the customers service, you manage all aspects related to customers (address, preferences, whatever). In the dashboard application, there's a map you want to display showing all of the names of customers and their locations. In other words, the dashboard service cares about a subset of the customer information (namely customer name and customer location).

My understanding is that it's an anti-pattern for the dashboard service to synchronously communicate with the customers service whenever it needs customer data to show the map. So instead you have a data store in the dashboard service's database with the customers and their location. When a customer is updated, an integration event is fired from the customer service and all downstream systems (aka. dashboard service) would get updated.

  1. Am I mostly correct in my analysis here or is there a better way to go about this?
  2. How would the dashboard service fetch the initial data of all of the customer's locations?
  • 1
    why would it be an anti pattern for something that wants customer data to use the customer service? – Ewan Aug 9 at 15:45
  • @Ewan my understanding is based off this, which says it can lead to brittle microservices: docs.microsoft.com/en-us/dotnet/standard/… – thebfactor Aug 9 at 15:52
  • "if your initial microservice needs data that is originally owned by other microservices, do not rely on making synchronous requests for that data" – thebfactor Aug 9 at 15:58
  • ahh yes I see what you mean. not sure it applies for your case though – Ewan Aug 9 at 16:23

So the async approach would be for the Customer service to raise an event when a customer changed and for the DashBoard service to listen for that event and update the map accordingly when it was received.

However. You should be careful not to duplicate the customer database. In your example you effectively need all the customers. If you use the CustomerUpdated event to make a copy of the customer db on every service that uses the customer data, that is not a good thing.

Querying the Customer service for this information (with appropriate caching) would probably be preferable to effectively replicating the customer database via events.

Instead say our map shows the density of customer per postcode. Then it makes more sense to use the async approach, as the aggregate information is derived from the customer info but not available through the service directly.

In either case with a new service you will need some initial population of the data.

People worry a lot about missed messages and keeping in sync, but if you have a good message queue you can rely on it working

You are correct that your services should not do synchronous requests to get data from other services, but you should not try to find an alternative way of getting the data. What you should do is find a way to avoid the need for the query altogether. What this means is that you need to reconsider what your services do and what data they own.

Normally, when you have services like CustomerService and, as you say, it manages all aspects of a customer, you can immediately tell that all other services will need to query CustomerService every time they need something related to a customer, so you'll be breaking the rule "don't do synchronous requests to other services" all the time.

Instead, create services based on "Business Capabilities", so that each service owns all the data and logic required to fulfill its purpose. For example, it's unlikely that you have a feature that requires the customer name and the customer location. Therefore, you will store the customer location in the service that needs the location and the name in the service that needs the name. This should remove most needs for querying data from one service to another.

Being more specific to your scenario: You'll have one service that will store UserId and UserName and another that will store UserId and UserLoation. When displaying the Dashboard, you might call the Service that owns the user location, and get all user Ids that are located within the geographic polygon that you want to display. Once you have these Ids, you can call the other service to get the User Names. This second call to get the names can be done either from the client or by an API layer, which won't contain any business logic, it will only know how to call the services to get the data to return to the client. So, you might get data from multiple services, but services won't call each other.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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