If you have been involved in the decision-making process, with reasonable doubts to start the next big software project using Microservices, you are not alone. Success stories told by software giants like Amazon, Netflix, eBay moving to Microservices inspires us. When you hear words like agility, speed, and scale who doesn’t want to try Microservices, right?

The story we don’t hear often is how they got there. If we look at almost all these software giants, none of them have started developing Microservices in the beginning as we know it. But one thing for sure is that, when they grow big, they will eventually end up with Microservices for apparent reasons.

Tip: use Bit to share and collaborate with your team on reusable JS modules and UI components.

Speed up development time and increase maintainability with reusable components that have been encapsulated with their dependencies and tested in isolation. Liberate your components — share them from any repo and import them into any repo, either as source code or as packages. Give it a try.

Identifying the bounded context is harder than you think

Well, before coming to any judgments, let’s understand the situation at hand. Let’s assume that we have decided to use Microservices for the next big software project. We typically begin with, identifying the bounded contexts to break down the Microservices. One of the important questions that we need to answer is, whether we have enough information at hand to identify the bounded contexts at the beginning? Some might say, we know the requirements and the domain of the business and why can’t we identify the bounded contexts that lead to service boundaries. Keep in mind that, recognizing the bounded contexts require way more, beyond the understanding of the domain, subdomains, and even the detailed requirements.

Bounded context thought experiment

Assume that we have divided the application domain into three bounded contexts, forming three Microservices at the beginning. Let’s also assume that two of the Microservices depends on the third one. This setup might work well in development. But what if when the application is in production, the shared Microservice team gets lots of change requests by the other two, which delays the overall project progress? This scenario is a practical example that is difficult to predict when starting to develop a new application unless its in production. Remember we want each Microservice team to self-organize and manage the work with minimal dependencies, beyond the service boundary. Similar problems don’t add up to the philosophy of self-organized teams working within the Microservice boundary.

So what’s the solution? Of cause, the real resolution depends on what caused the actual delay for the third team. But it could also be because we haven’t identified the bounded context accurately. We could have formed two Microservices only at the beginning, absorbing the functionality of the shared service, without having the dependency in the first place. This experience comes with time, running software applications in production. It is also important to note that these learnings are equally applicable to monoliths.

Breaking something you have is different from breaking an abstraction

If we already have a full-grown monolith running in production, then we are better equipped, having enough tacit knowledge to identify bounded contexts. Unfortunately, this knowledge isn’t always available when we start a new project.

When we start a new software project with Microservices and expect to achieve agility and speed before coming to the right scale, is harder than you think. The real challenge comes with the underlying nature of Microservices, which are distributed systems. Building a distributed system from the beginning will most likely slow you down unless you are at the right scale. If you believe this is an investment for the future, I guess you should know what you are doing and having enough experience building full-blown Microservices solutions in the past. It is because dividing Microservices comes with all sort of challenges in managing multiple runtime environments, databases, and integration points.

Let me take a simple example to explain the added complexity of distributed systems. Just think of the complexity involved in handling a sequence of actions that span across Microservices. You should know the pain and the complexity involved in having to implement Sagas or distributed transactions. For comparison, similar functionality could be easily achieved using a transaction block in a monolith.

If you decided to begin a new project with Microservices

Somehow if you have decided to start a new project with Microservices, make sure you know the risks at hand. The patterns and practices available out there are geared towards the technical solutions rather solving the practical problems at hand. So keep in mind that there isn't any guarantee on what works for them will work for you.

Besides, don’t stress too much on following the exact patterns and practices relevant to Microservices in the beginning. Use your common sense and experience to design the architecture to speed up work. As you already know in software, some problems are better to be solved later without putting lots of efforts upfront. So take differed decisions more often and avoid being fallen into the trap of building too many Microservices at the beginning unless you have real reasons to do it. And my final advice is, start small and scale towards more Microservices with maturity, keeping minimal dependency between Microservices.

Learn More