It has been a long time since microservices were introduced to the world. They had their ups – yeah, let’s use it everywhere – and downs – whaaat, modular monolith only. But that is not what this story will be about.
I would like to discuss whether the majority of projects based on microservices are actually based on them or something else. Something else? – you might ask. Do we really understand what they should be? Do not misunderstand me, I might be completely wrong but I have started to wonder and it has been bothering me.
Let’s take a look at one of the most popular examples from online tutorials and articles, which is an e-commerce-related domain. It can be built out of the following domains (I do not want to focus in this article on core, sub, and generic ones – that’s why I just call it domains):
After a deep analysis of requirements, potential traffic, security, fault tolerance, and many more it turned out that the application at the beginning will be small but has a very high potential for growth. The development team decided to follow the modular monolith – quite a smart decision at this point. Modules were created for each domain that was discovered:
So, there is e.g. Orders or Invoices module. After the first release, everything works as it should. However, after some time in production, the team noticed that:
– the Invoices module needed better scalability
– there are a lot of code changes in the Delivery module
– the Complaints module has a lot of errors that bring the entire application down
What usually happens is that the Invoices, Delivery, and Complaints modules are extracted to separate services. Each of them, of course, has its own database. The ecosystem becomes distributed:
And here we come to the point. Based on your experience – in how many cases would each separate service be called a microservice? Another question – if so, is it really a microservice? I used to like the definition – Not bigger than bounded context, not smaller than aggregate. But in practice (and in my opinion), such a bounded context is usually too big to fit the microservice.
Let’s take the first module – Invoices. It might:
– generate a new invoice when the order is made
– generate a correction invoice when the first one is incorrect
– merge several invoices into a single one
– export the invoice to PDF
– export the invoice to DOC
– export the invoice to PNG
– do many more
A pretty big responsibility, don’t you think? If so, should it really be called a microservice? Micro means something very small. Here, we deal with the entire module. So, what would be the microservice in this example?
Let’s assume that we as a team face a very poor performance on the export of invoices. After analysis, we can see that there is a lot of traffic and scaling can help us with this problem. What do we do? We subject our Invoices module to further granulation and extract InvoicesExport service:
Looking at the responsibility of the new module, you can say that it is very small. It has its own, single responsibility – the export of invoices. Yes, in the case of code volatility or high usage of PDF exports, it can be further split into other services but in our example, I assume it is used as much as other export types.
I can imagine that the Invoices module sends a message about the need for PDF invoice generation. It is then consumed by one of the instances of the InvoicesExport service and the invoice is generated. Further, the Notifications module takes this information and sends the email with the invoice to the buyer. In case of failure of the service, messages wait to be consumed later (or by the other instance) and the invoice is sent anyway.
Can I call the InvoicesExport a microservice? Yes, I can!
The above example shows that the term microservices can often be misused, especially when we translate an entire domain into such a service. I think this causes quite a bit of confusion and leads to situations where entire ecosystems are referred to as microservices, when in fact they are.
Maybe I’m exaggerating and it is not that important. But maybe it is time to think about another name for services like Invoices, Delivery, and Complaints. I personally like the term distributed modules.
And you, what do you think about all this?