Director of Avenga Labs
Microservice architectures are the default choice for building and modernizing enterprise solutions for our digitally driven business.
Adaption of this paradigm has happened relatively recently. However, the question now is how to do it properly and to a much lesser extent, if anyone should do it in the first place. It directly affects the flexibility, reliability, scalability and performance of your digital products.
Experience with microservices collected over time results in best practices, patterns to follow and anti-patterns to avoid.
IDEALS is considered an equivalent of the SOLID principles from object oriented design in the world of microservices. As you will see, not all of the SOLID principles have a direct translation into the microservice architecture and vice versa, but there are new principles which have no equivalent in SOLID.
→ An examination of decisive factors to help determine whether or not micro-services architecture can be of benefit to any given organization.
Let’s analyze briefly each letter from the acronym IDEALS.
APIs too often attempt to satisfy the needs of all the clients (API consumers). And as a result, they become a bloated set of services that are supposed to serve everyone but in reality are not efficient for any of the consumers.
Different interfaces should be available for different consumers. They may require different messages and contracts, different communication protocols (for example internal services may prefer gRPC over http), or a different aggregation of messages.
API Gateways are helpful, as well as back-end for front-end patterns. Our tool Couper.IO is a perfect solution for delivering APIs to multiple different consumers. It helps to segregate interfaces, depending on the clients, delivering exactly what they need.
The concern of application designers and developers has been the proper decomposition of software components into smaller parts with adequate responsibilities and functions.
Now, because of the distributed nature of microservices, deployment is a critical part which also affects the design of the components.
Continuous deployment means that often services are deployed in different versions, and you have to be fully aware of it. And of course, one of the key principles is that they have to always be ready to deploy.
Deployability, as a requirement, cannot be addressed “later” anymore.
Containers and container orchestrators, such as Kubernetes, have become the de facto industry standard for deployment. There are advanced tools for monitoring, tracing, and traffic management, and service meshes are growing in popularity.
Serverless architectures make it even easier to deploy fine grained functions as services.
Cloud service providers are competing to deliver the easiest and most comfortable solutions for DevOps teams.
To maximize flexibility, services are publishing events and responding to events. Event producers are not aware of their consumers and consumers can receive messages from different producers as long as the topic and schema is right.
This opens up an entire world of possibilities. For instance, when a new employee is hired, multiple services may react to it and new services interested in this event may be added later; all without modifying anything in the service which produced the event.
However, nothing comes without its price and the same applies to an event-driven approach.
Optimistic scenarios of workflows look easy and are easy to implement, but when you start treating the flows seriously you have to add failures, retries, aborts and compensation logic. Even relatively simple event flows and orchestrations become very complex graphs of dependencies.
Plus user interaction is often linear not event driven, so it also affects the consumers of the services, which have to be able to handle its asynchronous nature.
Fortunately there are new options and emerging standards to address those complexities.
→ Explore Asynchronous API standardization. AsyncAPI for faster and better digital communication
This is the most controversial principle. This principle promotes the availability of the services over data accuracy and consistency.
There are many business scenarios that do not tolerate inconsistencies and may result in financial losses, a degraded user experience, lost consumer trust, and even be a hazard to the environment and human life. Many examples refer to completely different business domains than yours, that are less regulated and usually more tolerable. For example, the inconsistency of social media posts between two devices (service clients) is fine, while having inaccurate medical lab test results is a serious problem.
→Have a look at Security-first system for COVID-19 test results in the blockchain
Be careful and analyze the business impact of the architectural decisions. Don’t jump on the eventual consistency bandwagon because it may seem fashionable to do so.
When used properly, which means when users clearly prefer faster information over its accuracy, it will be very beneficial for the performance and scalability of the digital solution.
Patterns such as Command Query Responsibility Segregation (CQRS) help to remove performance and scalability bottlenecks by separating read operations from operations which modify the state of the system.
CQRS can be taken even further with event sourcing strategy, which enables it to analyze and replay business transactions by storing a series of events which modify the state.
When we think about loose coupling in the microservice architecture arena, we often think about API gateways which enable the dynamic management of API providers and consumers. Gateways are an abstraction layer between the API consumers and the API providers.
Another approach is to build back-end for front-end APIs to tailor the APIs to the consumers, such as web apps or another service and mobile apps.
And let us remind you, you can have both with our Couper.IO tool which enables you to reuse your existing APIs and create multiple BFFs without needing to modify them.
What cannot be also forgotten is the loose coupling between different UI elements, as UI monoliths are still too common. Micro front-ends are something worth considering.
Another pattern to be followed is to have separated data storages for different microservices instead of a tight coupling on a single database which creates invisible dependencies, defying many benefits of microservice architecture.
Single responsibility means the given component is doing one thing and not the other. The same applies to microservices.
Adding too many functions to the microservice, well, makes it a small monolith with multiple internal dependencies.
On the other hand, making microservices too granular creates more latency due to the multiple calls required to perform even the simplest business functions.
Too coarse or too grain, that is the question.
The principles of IDEALS are an “executive summary” of the millions of hours of experiences with microservice architectures and practical problems faced every day by millions of developers, so they should not be ignored.
Ideas go back to the SOLID principles for OO (object-oriented) design, which makes it even more convincing that it’s the right path to follow.
Checking your solution architecture against the IDEALS set of principles is highly recommended. You can never go wrong with that, as you’ll see what you may be missing and decide if it’s worth it to adapt another principle in your particular business case.
→ Read more about Evolutionary architectures in practice
We advise more caution around the complexities of the blind overuse of the event-driven strategy as eventual consistency is recommended. With flexibility always comes additional complexity, please do value both every time.
And, you don’t have to do it alone, our solution architecture team would be glad to help with adopting IDEALS into your specific case. Architecture is never ideal (pun intended) but IDEALS applied properly can help to make it even better than it is now.
We asked Roland Guelle, VP of Technology at Avenga, to share his take on the IDEALS and if it’s truly a must-have, like SOLID has been for OO. Roland commented, “ IDEALS is a checklist to review your microservice architecture design. With good justification, some individual points can violate the principles. But if the number becomes greater than 2, it should be looked at more closely.”