ProfiSea

Sign in

Monolith vs. Microservices Architecture

ProfiSea Israel, DevOps Colledge

Continuing our journey on learning more about Microservices, today, we’re discussing the differences in following Monolithic and Microservices architecture patterns. As we’ve already investigated what microservices are, let’s start with the concept of the monolith.

Building a Monolithic App

The design philosophy behind the monolith approach is to make the stand-alone software responsible for a full cycle of designated functions, not just for one particular task. Take, for example, personal finance management apps and word processors — most of them had been using only the monolith basis until recently.

Following Monolith Pattern

The monolith formula is to model the app first. A team of business analysts, PMs, engineers, and architects create a project roadmap of how things are going to work at the scale. Where each form goes, what will be the user stories, business logic, how many shipment categories they will have, etc. A database will be responsible for storing all the app’s information; there also has to be an easy-to-navigate, intuitive user interface. So, basically, we have a frontend side that communicates with a backend side.

This backend is deployed exactly as a monolith with its own attached database. The app can also communicate with third-parties APIs, and it supports a full range of devices (desktop, mobile, tablets). Sounds familiar? It’s because we’re very accustomed to this architecture. It’s been working efficiently for us for a long time.

Why? Due to its simplicity in many fields:

• Simple Testing — having a monolith, you mostly test a single piece of software, with the occasional need to mock several external services for integration testing.

• Simple Deployment — you just need to deploy the final artifact of your monolith (WAR file or directory hierarchy) on the suitable runtime and configure the designated properties.

• Simple Scaling — you can scale and improve the app’s availability by running multiple copies of the software behind a load balancer.

Then why even bother about microservices? As with anything, there are two sides to the coin. Along with benefits, the monolith has a number of drawbacks. For instance, you might want to empower your shipment app with additional features. The app’s codebase has to grow by who knows how many lines. The team grows in size since you probably add more needed engineers. Here come the problems.

The bigger your app becomes, the harder for each new developer to show productivity right from the first days. It’s because the app’s codebase gets challenging to sort through or modify. Not to mention that you might need to set up several teams to maintain the particular functionalities of your massive monolith — for design, for frontend, for backend, for QA, for deployment. And these teams can’t work independently; they must coordinate their actions and efforts to meet each other at the redeployment stop.

So, at this stage, the drawbacks of the monolithic approach become more visible and significant:

The code has an enormous number of lines that not every developer is able to navigate through;

• New developers’ productivity is low;

• Monoliths have limited reusability;

• The app is difficult to modify and update, which slows down the development phase;

• The IDE overloads and becomes slower, less productive;

• The technical debt increases over time, but the tech stack must remain the same as at the start of development;

• Due to the lack of modularity, the code’s quality declines with each change being made;

• Continuous deployment of an entire app becomes harder and harder as the code grows;

• The operational agility collapses because of the frequent redeployment rounds;

• Scaling gets more complicated, one-dimensional due to the increasing volume of data — caching is less effective, memory consumption increases, and the app gets slower.

Just imagine, you need to change the database for one small part of your app. What to expect? A lot of redevelopment for several app’s sections, not just for that little feature. This comes along with huge risks of scaling the entire piece of software, slower deployment, and inability to predict if the redevelopment will even work.

Building a Microservices-based App

As the microservices are loosely-coupled, the dependencies between them and their end-users are minimal — the consumers won’t feel any changes in the implementation of the particular service. Combining robust API management and up-to-date cloud deployment and integration technologies, the microservice architecture pattern divides the monolith into a set of fully independent software units. This principle of modularity allows updating, modifying, and replacing the whole systems or service components, without any impact for end-users.

Therefore, the microservices bring the following benefits for your application:

• Principle of modularity increases the overall agility of the development process;

• High modularity, scalability, and reusability of the app’s logic parts;

• The development tech stack is unlimited;

• Easy code maintenance — fixing, modifying, and replacing the parts of your app doesn’t require wholesale redevelopment;

• Scalable and independent engineering teams — services are small, so you need only a handful of developers;

• New developers’ productivity is higher due to the smaller codebase;

• Services are independently developed and deployed artifacts, which significantly speeds up the time to market.

Summarizing

So, what about the microservices pattern? Business-oriented APIs represent their capabilities. Simply put, each microservice carries out a core business capability, a valuable asset to the business. These assets are highly scalable to be used in multiple contexts, without direct binding through must-have languages or shared libraries. Each service is reusable for more than one business process and over different business channels.

As the microservices are loosely-coupled, the dependencies between them and their end-users are minimal — the consumers won’t feel any changes in the implementation of the particular service. Combining robust API management and up-to-date cloud deployment and integration technologies, the microservice architecture pattern divides the monolith into a set of fully independent software units. This principle of modularity allows updating, modifying, and replacing the whole systems or service components, without any impact for end-users.

Therefore, the microservices bring the following benefits for your application:

• Principle of modularity increases the overall agility of the development process;

• High modularity, scalability, and reusability of the app’s logic parts;

• The development tech stack is unlimited;

• Easy code maintenance — fixing, modifying, and replacing the parts of your app doesn’t require wholesale redevelopment;

• Scalable and independent engineering teams — services are small, so you need only a handful of developers;

• New developers’ productivity is higher due to the smaller codebase;

• Services are independently developed and deployed artifacts, which significantly speeds up the time to market.

Following Microservices Pattern

Exploring the main domain of the shipment services, we can roughly subdivide it into 3 subdomains:

• The user subdomain that will deal with user authentication and management.

• The order processing subdomain that will be responsible for the full cycle of orders processing — price calculation, invoices, discounts, and delivery options.

• The admin subdomain related to the supplier’s side and management of workers responsible for delivery.

Now you have to have clear connections between these subdomains. Remember, your microservices should be totally independent of each other. So, you need to follow the domain-driven design techniques and patterns to design an appropriate model. First, you should duplicate the features that actually depend on each other in all subdomains to make them separate entities. Then, each subdomain will process its own data on its own terms, so there have to be separate databases for each of the three. Avoid sharing databases — it’s bad manners in the world of microservices.

When these things are cleared up, you’ll end up with a map of services for each domain that can be put into design and production. Having small parts of the software to develop, test, and deploy, your team will work faster and more productive, avoiding overloaded IDE, limited tech stack, and overall chaos related to redeployment.

Summarizing

A boutique company of DevOps and Cloud professionals, providing a wide range of Digital Transformation services. https://www.profisea.com