This article builds on my previous post, Enterprise Software Development in 2019, and outlines a rough approach to taking that monolithic monster and turning it into a lean and agile set of micro-services, which can be built, deployed, and maintained with ease. Note that this is not a particularly technical article, and was written to justify a migration from a business case perspective. Any references to modules do not equate to domain specific logic, but application functionality.
To dig in a little deeper, let’s start by explaining what we mean by these terms:
In a monolithic architecture, the user interface, data access, and everything else you can imagine is developed in a single solution. Generally speaking, it is a single-tiered approach to software development, where everything relating to the application is tightly coupled together.
On the other hand, in a microservices architecture, the application is arranged or formed as a decoupled service series. In basic terms, it’s a combination of smaller applications or services have combined to make a more significant service, resulting in the complete package.
Reasons to Decouple
Before we cover the steps to transition from monolithic to microservices architectures, I will briefly touch on why it’s essential to consider this early on in your technical scaling journey. Many start-ups set off on their journey with modest ambitions, and scale-up is not at the forefront of their minds. Instead, jamming every single feature into their application delights users but creates a massive headache for growth. I’ve outlined the top 3 reasons to de-couple below, but there are hundreds more benefits for the teams involved hidden below the surface, from escaping merge conflict hell, right through to clearer definition of system function and separation of concerns.
As time passes, data for any system is getting more and more complex. If too much data fills up an application, it would become harder and harder to manage with time. Moreover, if you want to add some new components, it will become a job that “almost” impossible to achieve.
Efficiency and Reliability
In today’s world, with super-fast applications and reactive front-end frameworks, people have largely run out of time patience, and they cannot tolerate tasks taking a lot of time.
Monolithic Architecture = Outdated
Over time, the monolithic architecture will feel more and more outdated. There’s still a place for this architecture style; however, for modern web apps, this is changing fast.
Transitioning Monolith to Microservices
Now let’s focus on how you can transition your application or system from a monolithic architecture to microservices.
Identify Existing Modules
First, you have to identify the existing modules in your system. The modules could be specific functions that perform specific tasks either on the back-end or at the user’s direction. Do note that the bigger and more complex a system would be, the harder it would be and the longer it would take for you to identify all the modules.
Identify Modules with Dependencies
Exploring dependencies is a massive part of the preparation process for any migration. Split code into groups by function, ready to rewrite into services, using whichever technologies you choose, but remember that your goal is that when these modules are isolated, they can act as a unique service of the application.
Remove Duplicate Work
Since monolithic software is not the easiest to maintain or manage at scale, the chances of duplication (e.g. non-DRY code) is relatively high. This means that the same code is present in multiple locations within your solution; unbelievably bad practice! In the case of a database, it could be multiple tables for the same thing, or for code, it relates to multiple functions, repeated in the code, but doing the same thing. You have to identify and remove all these duplications so the system can become more transferable.
Prepare UI Layer
It is more than likely that a goal of migrating to micro-services is to make your application easier to manage, so creating a new user interface might be essential. Note that the interface that exists in the monolithic system may not be as usable because it is probably so tightly coupled to back-end code, so factor this into your plans!
Transform Modules to Microservices
This step should be a little easier if you follow the steps above. Unless we’re changing platforms, the goal here isn’t to rewrite the application, it’s to change the architecture, enabling us to make changes in the future in a managed way. So, migrate modules one by one and add them in microservices architecture until everything has been successfully decoupled.
Test, Debug & Deploy
Note that this process requires a LOT of testing time. Engage your testing team, and iterate it to perfection. Deciding how to deploy your micro-services (whether you’ve designed for containers, etc.) is another subject I’ll cover soon.
Benefits of Microservices Architecture
If you still feel like this transition is not worth it, or you’re coping just fine the way things are, start to think about growth, extensibility and long term maintainability of your solution.
In a microservices architecture, the software or its components can easily be integrated or linked with other systems and software. It allows for more dynamic handling and can open bigger doors for better implementation of these systems. In other words, better integration enhanced reusability.
One of the priorities in software development is to develop an application that is maintainable, i.e., that can be properly updated and managed with changing time and changing requirements. While you can maintain a monolithic application, that is considerably harder and may require a lot of people to manage just one application, at times.
If you’re on the road to growth, transition to microservices early for the sanity of your future self and your team!