Microservice architecture is a hot topic nowadays. Despite its complexity (distributed transactions, eventual consistency, operational overhead), it is inevitable, especially because of the many benefits (polyglot architecture, selective scalability, strong modularity, fault tolerance, experimentation, agility, etc.) that it offers.
Microservices is probably not something new to you. I still remember, back in 2o11, I worked on a SaaS product in which we tried to build similar architecture containing different bounded contexts including agile project management, issue tracker, and collaboration. Although, at that time we were not familiar with the microservice fancy terminology, but the benefits we were seeking, were similar to what microservice architecture offers. Initially, the decision to distribute the application in various modules worked very well, but we screwed it up during the integration phase. Instead of sharing the information between different modules by embracing event-driven architecture, we decided to make direct synchronous calls. This drifted us away from the original motivation of independent deployment, development, and runtime.
This article discusses another lesson learned from one of my recent projects to help you in identifying microservices boundaries from different viewpoints. To begin the discussion on what could we do differently, it is important to first have an overview of the system under discussion.
Next Generation Border (NGB) system is an improved version of passport control system. The principal objective of NGB is to expedite the process of entertaining passengers at immigration counters in airports. The system improved the passenger experience by reducing the processing time from 56 seconds to 10 seconds on average. Below is a context map of the Next Generation Border system.
The bounded contexts highlighted in red contribute to the NGB system. Some of the bounded contexts are intentionally omitted to keep the discussion more focused.
At the heart of the NGB system is the preclearance process. The preclearance process generally starts 72 hours before passenger check-in. Airlines send the reservation information to advance passenger information system, owned by some other entity, which forwards the information to NGB system for preclearance. During preclearance, NGB executes various checks on passenger's profile with the help of immigration system and sends the findings to back office for reviewal in case the passenger is found guilty because of any issue (i.e., blacklist). The passenger found not guilty is marked green and it takes few seconds to process such passenger at the immigration counter.
I hope you now have got some idea about the NGB system. Let's begin with the retrospective.
What Went Well?
As most of the literature dictates in defining microservices boundaries in light of linguistic boundary as bounded context, NGB was divided into Automated Preclearance, Passenger Border Control, and Notification bounded contexts. The Automated Preclearance context processes a stream of reservation data in the background and hands it over to Passenger Border Control context for persistence and human intervention. This context has two main categories of users: frontline users who are passenger-facing users, and back office users who process passengers with any issues in their absence. Notification context, as its name suggests, is used for sending the notifications to the system users.
What Went Wrong?
Although the ubiquitous language used in Passenger Border Control context was specific and distinctive, it still was not sufficient. As the time passed, the Passenger Border Control context not only started to become monolithic but also started to give trouble while rolling out changes in production. Any changes we make for the back office operations has to be carefully done to avoid any impact on frontline operations. Moreover, any changes that impact only back office operations cannot be deployed in isolation without impacting frontline operations and vice versa.
What Could We Do Differently?
Before getting into the discussion on what could we do differently, let's have a quick look at the business process view of NGB system shown below:
The dashed arrows depict that the business processes occur at different timelines. For example, booking information is generally received 72 hours before flight departure and back office users review passengers few hours before their departure, whereas passenger passport control happens when passenger reaches the counter.
If you notice in the preceding context map, the Automated Preclearance process was already taken out into a separate bounded context, whereas back office process and frontline process were captivated in single Passenger Border Control context. The reason they were put into the same bounded context is because of the linguistic boundary. To overcome the problems highlighted in the last section, we could have distributed the bounded contexts as below:
Once again, some of the bounded contexts from preceding context map are intentionally omitted to keep the discussion focused. The Passenger Border Control context is now further divided into three different contexts as highlighted in bold red circles. Both Back Office and Frontline border control contexts will keep the minimal structure of the passenger domain model as shared kernel with respect to the context, whereas the complete passenger domain model will be event-sourced in the Passenger Travel context. All the other three contexts will send events at various timeframes such as the start of automated preclearance, reviewal in the back office, passenger travel recording at the frontline, and so on to the Passenger Travel context. This way the Passenger Travel context will act like a headless microservice. Moreover, this will also segregate the read and write responsibilities (CQRS) within NGB system.
In this manner of distribution, the Passenger Border Control context will not only reduce the change impact of back office and front office on each other but will also help in rolling out the change independently. The only tradeoff with this approach is that we have to keep multiple copies of passenger domain model in multiple contexts, that is unavoidable to achieve desired cohesiveness.
Determining microservice boundaries from bounded context viewpoint can be a good start. Relying only on bounded context viewpoint may not always suffice. Other viewpoints are also vital to determine microservice boundaries. Viewpoints like Selective Scaling, Changeability, Deployability, Testability, Business Process, and Organization Communication Structure (Conway's Law) also influence microservice boundaries.