I often use the term "nano service", but I figured that I had never defined this, that I will do in this post. In order to understand nano services we need to understand microservices first.
What is a microservice and nano service
We will use Lewis and Fowler's definition of microservices:
"is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies".
All of the above can be said about nano services, except "built around business capabilities". We will refrain to define microservices' size in terms of lines of code or any other measurable way, we define them as owning a business capability.
A nano service is therefore:
"a (micro)service which does not fully own a business capability".
An often used example of this would be if we split CRUD methods into different services. However this is a terrible example as each of these services would need their own database, they would also change together, as the information which can be updated also needs to be fetched (get). This would also violate the microservice principles.
A better example would be if for example the validation of a service's entity is split into a seperate service. Let us say we have a person entity, which is owned by a microservice which has the business capability of storing and providing information on persons. I have often seen (and done), the validation split into a seperate service. So that there is a PeopleValidationService and a PeopleService. This is not a great design with microservices. The PeopleValidationService and the PeopleService often (always?) change together. If a new field is added to our data on people, we will likely want to validate this. The validation service has little purpose in this, and is a nano service.
Should my services be nano or micro?
The smaller our services are (when we have more services) the more we have to manage. As each service has its own deployment pipeline, its own database and needs to be updated over time. There is also more to clean up when we need to remove a service (Git repo, pipeline etc..).
However the more fine grained our services are the less we can deploy/change at a time, which is an advantage as when we deploy big changes it can be hard to know what breaks. Overall it is easier to work with small controllable changes. But it is more cumbersome to handle many small moving parts. Often when services exchange data, it is forwarded multiple times. An example may be that Service A creates the data but it passes through Service, B, C and D before it hits service E. Every single service in the flow needs to be changed before Service E can use this data. In this scenario the deployment of these services needs to be coordinated. If A and C is changed but B is not, B cannot pass on the data. With fewer services there would be less to coordinate.
Our development tools are also made to work with single code bases. Some code bases are smaller and some are larger, but the more services you have the more projects you will have open when developing a system.
The more services the more network traffic we will also have. You may be familiar with the fallacies of distributed systems:
- The network is reliable
- Latency is zero
- Bandwidth is infinite
- The network is secure
- Topology doesn't change
- There is one administrator
- Transport cost is zero
- The network is homogeneous
The more distributed our system is, the more we need to handle the above.
Overall the smaller our services are, the bigger the hit is from network complexities, maintenance and need for tooling. However we gain more fine-grained scaling and changeability.
Often I have found nano services to be more trouble. Especially when business logic has been spread across multiple services. However in some situations nano services make great sense, such if you have a legacy system that is cumbersome to communicate with. Here a nano service can be put in front of the legacy system, that handles the communication towards the legacy system - making a technological bridge. This makes it possible to move cumbersome communication methods and legacy logic to a single service. This makes the other services simpler, as they no longer need ancient dll's, typesets or communication protocols. Nano services are great for filling technological gaps.
There is no reason why a platform cannot have both micro and nano services. If you are able to handle microservices you are likely able to handle nano services as well - it mostly comes down to granularity but your discoverability and maintainability may be challenged.