For many years, code was written to create applications that got bigger and bigger, which we now call monolithic. Then we understood that this application was a big problem for businesses. Here are the main problems we have found with monolithic applications.
Reduced development speed: a large monolithic application makes development more complex and slower.
Scalability: scaling of individual components is not possible.
Reliability: failures in one module can affect the availability of the entire application.
Non-Agile development: Often more teams found a conflict in development code because they were working on the same code repository for different projects.
Lack of flexibility: a monolith is constrained by the technologies already used in the monolith itself.
Deployment: a minor change to a monolithic application requires a re-deployment of the entire monolith.
In recent years, many companies have migrated their monoliths to microservices architectures. Theoretically, I can assure you that it's the best choice, but in practice, there are different control indicators. Let's focus on the advantages of microservices over monoliths.
Improved scalability: because each service is a separate component, it is possible to scale a single function or service without having to scale the entire application.
Right tool for the right function: with microservices, it is possible to achieve greater independence from suppliers by choosing the right tool for each function. Each service can be written in its own programming language, can use its own structure and utilities, and can communicate with the other services in the application.
Increased resilience: with microservices, the entire application is decentralised and decoupled into services that act as separate entities. Unlike monolithic architecture, where a bug in the code affects more than one service or function, the impact of a bug in this architecture is minimal.
Faster deployment times: in monolithic architectures, changes require redeploying the entire application. A microservices architecture enables faster releases because each service is developed and deployed independently, reducing the risk and time associated with coordinating changes across an entire application.
Greater cost efficiency: activities are focused on specific services, reducing the overall cost of developing and maintaining the system. Teams work on specific functionalities, ensuring that resources are used efficiently without redundancy or excess.
Now let's talk about the drawbacks. When using microservice architecture there are two main disadvantages, in this article we'll focus on these ones and try to find a solution.
The first contraindication is the cost of the infrastructure, but we won't talk about this because it was discussed in a previous article that you can find here.
The second contradiction we're going to talk about in this article is the implementation effort. Building a microservices architecture is very expensive, both in terms of development and in terms of maintenance and monitoring. It's important not to underestimate the difficulty of the design, a bad design will become the most important problem.
There are companies that start a project with microservices and then come back because they understand that they are not ready for this architectural solution. Instead, there are companies that start migrating their monoliths to microservices and then stop because it's too expensive or too complicated.
The solution I want to recommend to you today is semi-monolithic architecture. I am talking about a hybrid architecture that uses monolithic and microservices in total harmony.
The image above shows a hybrid microservices and monolithic architecture.
I think that when you start a project you need to build a monolithic application. By monolithic I mean a large application that handles a significant part of the application domain. There may be more than one monolith in an organisation. The first thing you need to think about is dividing the application domain into a few parts and creating a monolithic application for each of them. You can think that a monolith needs to be only one, at actually we talk about monolith every time we have an application as managing a large part of the domain. So in a company there can be more monolithic application.
If you need a common part for multiple monoliths, you can create a microservice instead of a library, giving you a piece of code that can be written in a different language, updated and deployed independently of other applications.
Sometimes we need to create a microservice for a critical part that we can't scale horizontally. There are cases where we'll create a new microservice just because there's more functionality that's better implemented in a particular language.
In this type of architecture, it's very important that services communicate with them in asynchronous mode, using message queues such as SQS in AWS services. For communication from monoliths to microservices we can use http protocol for example.
Another important concept is that there will be no database sharing by applications. Each microservice will have its own database and will not access another microservice's database. This is fundamental when we use a modern ORM for database maintenance with migrations. Of course, the same is true for monoliths.
This solution allows us to create a hybrid architecture that uses microservices without abusing them. In this way, we can reduce infrastructure and development costs while taking advantage of the key benefits of microservices.