In recent years, one often hears about microservices when talking about architecture. The impression could almost be given that microservices are the new standard to be used all the time. However, there has been no lack of growing criticism of this architecture: it is often over-engineered, complex and, in general, it takes too long to develop and operate microservices. The main alternative is the monolithic architecture, which is considered by some to be dead. This raises the question: does it still make sense to work with a monolith?
Microservices offer a whole range of advantages, but this also applies to monoliths. They are simply different advantages that we will explore in this article.
Monolithic architecture is the historical form of application development, because it is simply a single application. The important point is that by monolith we mean the architecture of the system, consisting of a single block for the entire application developed, and not the way in which the functionality of the software is realised, which is the software architecture.
This means that a monolith, from the system's point of view, can also work internally with components or layers, the only important thing being that it is a single process.
And since it is a single process, from the system's point of view it is always an all or nothing decision. So if I decide to release a monolith, I have to release the whole monolith or nothing, I cannot release just a part of it. The big advantage is that development is much simpler, because I have everything I need for the application. This means that I can combine, run, test and distribute everything together without having to make integrations. I thus have a self-contained application and that is good, because once it is up and running and running consistently, I no longer have to think about integrations.
Furthermore, having all the components in one application makes it easier for me to carry out tests or debugging activities. Finally, with this type of architecture, it is also easier to manage security as the possible points of attack are reduced.
With more complex applications, there is often a desire or need to control everything at a more granular level and to be able to easily scale our application or parts of it. In this case, the question is: how do I synchronise the different nodes that are created when I run a scalable application?
This synchronisation is often done through a common database and this database becomes the single point of failure (SPOF), i.e. if the database is down, everything is down because I don't have a real distributed system and I don't have independence.
What you want is more independence, you want to be able to separate applications from each other and this does not work with a monolith because it was not designed for this
This is where the idea of microservices comes in, whereby individual isolated services that are self-contained and function autonomously are usually already physically separated. I therefore have several separate applications that talk to each other, each taking on a well-defined set of functionalities. Communication between the individual nodes takes place by interacting via APIs, which are built on the basis of REST, GraphQL or other protocols such as RabbitMQ, and thus a certain separation is achieved.
When communicating via HTTP or any other network protocol, one must anticipate that an endpoint may not be accessible. This means that one has to think about retrial mechanisms or the like, and from here the transition to the use message queues is short. This entails a completely different way of thinking about, developing, distributing and managing software. This is not a better or worse solution per se, but simply different because it is aimed at other scenarios or use cases.
The autonomy of microservices goes even further. This applies not only to operational activities, but also to development. As long as the interfaces are clearly defined, the individual services that I want to interconnect later can be developed independently of each other. I can also do this in several teams and in parallel, which leads to a greater overall speed than if everyone were working on the same software at the same time.
Finally, individual components can be realised using different programming languages. This facilitates both development and testing, because the individual services are smaller and more manageable. Anything smaller is easier to test, document, update and so on.
All these aspects would suggest that microservices are the best choice. However, as we said at the beginning, not everything is suitable for microservices.
Neither microservices nor monolithic architecture are the perfect solution. Both may or may not be an optimal choice.
For a given task, you need the right tool that can best solve it. If you choose the wrong one, at the end of the day you have problems that are far more serious than the tool itself, because you have gone in the wrong direction.
It must also be considered that migrating a monolith to microservices or vice versa is relatively complicated.
What is your experience in this regard? Do you prefer working with a monolithic architecture or with microservices?
Let us know by leaving a comment.