Microservices or monolith?

Comparison of microservices and monolithic software architecture

Defining an application's structure is an important part of a software engineer's job. The application's stability, reliability, and ease of adding new functionality depend on a properly defined structure.

It's often difficult to determine definitively whether an application's structure is defined correctly. A software engineer is a specialist who solves problems using technical means. It's important to understand the tasks assigned to the engineers, the deadlines set, whether the technical specifications changed during the process, whether the engineers were sufficiently qualified to solve the problem, and whether the engineers participated in decisions regarding the application's structure.

The technical solutions proposed by the engineer must correspond to the tasks defined by the client. What's right for one task may not be right for another. It's probably not a good idea to deploy a single-page website in Kubernetes, configure load balancing, or create autoscaling. A virtual VPS server (or hosting) with a pre-installed content management system (CMS) or framework is perfectly suitable for this task. If this seems too complex, you can use a website builder (for example, Tilda). However, for a high-load application, Kubernetes is the optimal choice.

When we talk about choosing between a microservices and a monolithic application structure, we mean that we are designing a complex system with a high load. It's time to define the terms. By a monolithic application structure, we mean an application in which all the application code is located in a single location and does not require network communication to access application methods. By a microservices structure, we mean an application consisting of parts that interact with each other via network communication.

A common drawback of monolithic structures is that a fix in one place may break in another. However, this is not a problem with the monolithic structure per se, but with errors in the monolith's design. A fairly common practice nowadays is to create a monolithic application consisting of modules/components/packages that have a separate Git repository and are integrated into the project as needed. This allows you to design a monolithic application so that it consists of relatively independent components.

The problem with microservices is that as soon as we isolate one microservice in an application, we have to think about how we'll access it and how the services will communicate with each other. We'll incur transaction costs for transmitting data over the network. Deployment can be difficult if fixes to a microservice can affect the operation of other services dependent on it.

The conclusion is quite simple: if it's possible to stay within the monolith, then you should. Decoupling microservices isn't about improving code; it's a way to solve emerging problems. For example, let's say we have several applications and want to create a unified authorization system across them. Register in one and you gain access to all the others. We could create a separate authorization system for each application, but then it would be difficult to avoid code duplication, and each application would have access to the user database. In this case, it seems logical to isolate the functionality related to authorization into a separate microservice, and all other applications will access only it.