
Business events
As the system evolves, the services will start aggregating into natural allies. This means finding out whether the services are depending on a similar set of data elements or providing overlapping/side-kick functionality, and can potentially be part of the same bounded context.
Services within the bounded context working within the same domain might need to rely on the master for accurate functioning. This might mean, some of the master service data attributes need to be made available to the associated bounded context services. For example, in our previous example, we talked of customer preferences. Now, these preferences might need to be mapped to the location (address) of the customer. In this case, should the customer preference call the customer address service every time to build the preferences or can it copy the relevant attributes to its own domain? Without duplication of data, the two services start getting coupled tightly, leading to a two-way communication model. To break this tight coupling, we allow the customer preferences service to cache or duplicate the relevant customer attributes using the events. This asynchronous model breaks the temporal tight coupling between the services. Whenever there is a change of customer address, the service publishes a business event for the requisite change. The change is subscribed by the customer preferences, which picks up the change to update its preferences model.
This asynchronous model allows us to make sure:
- Ownership of data is still clear. Any change to data is declared to the dependent services. The dependent services are allowed to hold or duplicate data, but not change the local copy unless the master copy is updated (golden source principle). The dependent services store only the subset of data that is required and functionally relevant (need-to-know principle).
- Asynchronous business events lead to low coupling between services. Core service changes result in an event. Events travel downstream to interested dependent services. The only dependency is the format of the business event published.
- Downstream services follow the eventual consistency principle; all business events are stored in a sequential manner to construct/state a later time (event sourcing/CQRS). Query models can be different from the system of record.
- Asynchronous models of business events also promote choreography over orchestration, leading to loosely coupled systems/services.
At times, when teams start on a new product, an upfront definition of bounded context or services decomposition might not be possible. So, teams start building the application as a monolithic application by exposing its functionality as a set of services. As the team implements more stories, they can identify pieces of functionality that are changing at a fast pace (typically experience or channel services) versus slow changing pieces (typically core services or entity services).
The team can start putting the services into two categories—experience and system services. System services can further be grouped together around entities and interrelations. Experience services are mapped to the customer journeys. Teams will typically have sprints just to clean/refactor the code to clear the technical debt that accumulates with every cycle.
So, the next question is, what identifies a service as a microservice?