Micro-services, although undeniably the flavor of the season, is a much-misunderstood architecture concept. The confusion, in my opinion is due to the term itself. A more appropriate term, for instance, something along the lines of ‘Independent Business Vertical Component’ would have been relevant to the architecture, though been less appealing or glamorous.
It is important to understand the misconceptions surrounding micro-services and its impact on the way they are used. The word ‘Micro’ forces people to think too ‘granular’, often compromising independence of micro-services and even causing unnecessary overheads. It is not uncommon for example, to see teams create 100+ micro-services in a project that addresses a narrow business context. Consequently, the independent nature of the services is diluted. The services become chatty and rely overly on each other to complete a transaction. The questions we need to ask – is the designed granularity worth the overheads of data model separation, inter-service communication, containerization and management of all these services? Is it creating an additional operational coordination burden, rather than slashing?
Similarly, the term ‘Services’ on the other side of the hyphen steer people toward technical implementation, rather than thinking about ‘business’ services. There are countless e-books and white papers that talk about ‘micro-services’ patterns. However, most of these ‘patterns’ refer to the technical implementation of REST services and leave out business design of the services. Consequently, the developers are indulging more in technical nitty-gritties, sidelining the whole ‘business independence’ idea of the micro-services.
It will serve better to stress on the ‘Design’ of micro-services (‘bounded context’ principle etc.), more than the ‘Implementation’. The granularity of services should be driven by the smallest independent business context, and not by arbitrary rules such as 2 Pizza team. The patterns should address ‘independence’ through abstraction, event-based service communication etc.
Another critical point that merits attention is the overall operational complexity that is introduced. For instance, if you have implemented a “database per service” pattern to keep the teams independent, you will most likely implement the Command Query Responsibility Segregation pattern to have a read-only replica supporting the presentation views. To maintain the replica up-to-date, you will then require event based publisher/subscriber architecture. The complexities of maintaining this architecture increases with the granularity of services.
Micro-services architecture is often regarded as a cure to ‘monolithic’ applications, however, it is much more than a way to achieve modularity. The primary objective of the micro-services architecture is to achieve ‘independence’ of services and ‘speed of delivery’. However, this is often achieved at the expense of operational ‘simplicity’, so it is very important to take a call on where you will use micro-services architecture.
In my opinion, micro-services architecture is an excellent choice for core business functionalities where the ‘time to market’ is critical. In such scenarios, additional complexities are acceptable, considering the benefits of speed. However, for all other requirements, it would be prudent to stick to a modular, but a simpler architecture with good-old SOA principles and a common data model.