Найти тему
Funny programmer

How to boil porridge from microservices. Part 1

One of the reasons for the popularity of microservices is the possibility of autonomous and independent development. In fact, the microservice architecture means that the possibility of autonomous development can be exchanged for a more complicated (compared to monolithic) depression, testing, debates, and monitoring.

But you should take into account that microservices do not forgive errors of responsibility sharing. If the division of responsibilities is wrong, there are frequency-dependent changes in different services. And it is much more painful and complicated than agreed changes within the framework of different modules or packages inside the monolith. Coordinated changes in microservices are complicated by coordinated computation, deposition, testing, etc.

And I would like to talk about different patterns and antipatterns of responsibility division into microservices.

Service being as an antipattern

"Service-substantiality" is one of the possible (anti)-patterns of micro-service architecture design, which leads to a strongly-dependent code in different services and is poorly linked inside the services.

It seems to most developers that by selecting services by their subject area's essence: A "deal", "person", "client", "order", "pictures", he follows the principles of sole responsibility, and moreover, it often seems logical. But the "service is essence" approach can turn into an antipattern. This is because most bugs or changes affect several entities, not one. As a result, each such service combines the logic of different business processes.

For example, let's take an online store. We decided to highlight the services "product", "order", "client".

What changes and what services should be made to add home delivery?

For example, you can do this:

- in the "order" service add the delivery address, the desired time and the supplier
- add a list of selected delivery addresses for the client in the "client" service
- in the "goods" service add the essence of the list of goods

A separate API method in the "order" service will need to be created for the delivery interface, which will give the list of orders assigned to this particular delivery company. In addition, you will need methods to remove the goods from the order, which are not suitable or refused by the customer at the time of delivery.

https://pixabay.com/ru/illustrations/%D1%81%D0%BE%D1%86%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5-%D1%81%D0%B5%D1%82%D0%B8-%D0%BC%D0%B0%D1%80%D0%BA%D0%B5%D1%82%D0%B8%D0%BD%D0%B3%D0%B0-%D0%B1%D0%B8%D0%B7%D0%BD%D0%B5%D1%81-2187996/
https://pixabay.com/ru/illustrations/%D1%81%D0%BE%D1%86%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5-%D1%81%D0%B5%D1%82%D0%B8-%D0%BC%D0%B0%D1%80%D0%BA%D0%B5%D1%82%D0%B8%D0%BD%D0%B3%D0%B0-%D0%B1%D0%B8%D0%B7%D0%BD%D0%B5%D1%81-2187996/

Or what changes and services should be made to add discounts on promo code?
At least it is necessary:

- Add a promotion code to the "order" service
- in the "goods" service add whether discounts on promotional code are valid for these goods
- in the "client" service add the list of promotional codes issued to the client

In the manager interface, adding a personalized promotion code to a client is a separate method in the client service, which is available only to store managers, but not to the client himself. And in the "product" service to make a method that gives a list of products for which the promo code is valid so that the client can easily choose in his interface.

Sources of changes in the service can be several business processes - selection and design, payment and billing, delivery. Each of the problem areas has its own limitations, options and requirements for ordering. As a result, it turns out that the service "goods" we have stored information about the goods, discounts, product balances in the warehouses. And the "order" stores the logic of the supplier's work.

In other words, a change in business logic, which is spread over several services, leads to dependent changes in several services. And in this case, in one service there is a code which is not connected with each other.
Storage services

It seems that this problem can be solved by creating a separate "layer" of service over the services-entities that encapsulate the entire logic. But it usually ends badly, too. Because then services-essences become storage services, i.e. all business logic is washed out of them, except for storage.

If the data are stored in different databases, on different machines, we.

We lose productivity because we give the data not directly from the database but through the service layer
lose flexibility because the service API is usually much less flexible than SQL or any other query language
We lose flexibility because it is difficult to make data merge from different services

If different services-essences have access to other databases, then communication between services occurs implicitly - through a common database, then to make any change affecting the data schema change is possible only after checking that this change will not break all other services that use this database or plate.

In addition to complex development, such services become over-critical and heavily loaded - almost every time a top-level service is requested, it is necessary to make several requests to different services-essences, and therefore, changes in them become even more difficult in order to meet the increased requirements of reliability and performance.

To be continued in the next part https://zen.yandex.ru/media/id/5d7f7f203639e600ac6686e5/how-to-boil-porridge-from-microservices-part-2-5d8ed013e882c300b2c66a4c