Sponsor: Do you build complex software systems? See how NServiceBus makes it easier to design, build, and manage software systems that use message queues to achieve loose coupling. Get started for free.
How do you share data between services? This is one of the most common questions when you have a system composed of many different services, and each service owns a data set. For example, you may need data from another service for validation or to send data to another service as part of a workflow. I will explain a few situations where you could share data between services, but more importantly, when you shouldn’t.
Check out my YouTube channel, where I post all kinds of content accompanying my posts, including this video showing everything in this post.
A common situation is thinking you need to call another service to perform some action because you need to provide it with the required data. This is because data is being passed around services rather than living with the service that owns it.
For example, an order is placed through an e-commerce checkout process. The assumption is the Ordering service owns the entire checkout process and needs to call the shipping service with the order’s shipping details.
We need data in the correct place to avoid this service-to-service communication between Ordering and Shipping services. Instead, the checkout process involves each service as a part of the workflow.
The first part of the checkout process would be the client calling the Ordering service to start the checkout process. This could include the ordering service returning an identifier.
Next, the client would send the shipping service the address and other required details. This information would correlate with the identifier used in the first step.
Finally, the client would complete the checkout process and place the order with the Ordering Service. At this point, the ordering service persists the order and can publish an OrderPlaced event with the checkout process identifier.
Now we’re temporally decoupled, and the shipping and ordering services aren’t communicating directly. We simply are using publish-subscribe (or a queue).
The shipping service will then consume that OrderPlaced event. Since it contains the identifier used in the checkout process, the shipping service already has all the information in its own local database.
So if you need data from another service or you need to send data to another service, ask yourself why a single service owns the entire workflow.
Sometimes, you need data from another service for validation purposes or to persist with your own service state. I’m not referring to reporting or query purposes. I’ve discussed that in my post on The Challenge of Microservices: UI Composition.
You have an action/command to perform and must call another service to get data. It could be for validation, or you must save that data with your own state.
The important aspect is what type of data you request from another service. If it’s reference data from a supporting service boundary that’s non-volatile, then you have options. If it’s transactional data, I suspect you might have some service boundaries that aren’t entirely aligned with the business processes.
I mention non-volatile because the frequency of the data changing and the validity of the reference data play a role in whether it is plausible to have data from another service.
For example, our Sales service needs currency exchange rates when placing orders.
I mentioned earlier the validity of the data. In the case of currency exchange, it may be acceptable for Sales to use the exchange rate given for the entirety of a day. We only need to get the exchange rate between two currencies once within a day.
We then can cache currency exchange rates within the sales boundary.
Because the validity is a day, old exchange rates are still valid for orders for the same day. It’s historical data that isn’t going to change.
The exchange rate service owns exchange rate data. However, because its data is valid for a window of time (a day), this limits the number of calls we need to make to it, which also helps the availability of our Sales service.
Developer-level members of my YouTube channel or Patreon get access to a private Discord server to chat with other developers about Software Architecture and Design and access to source code for any working demo application I post on my blog or YouTube. Check out my Patreon or YouTube Membership for more info.
- Microservices gets it WRONG defining Service Boundaries
- The Challenge of Microservices: UI Composition