The sidecar pattern is a structural pattern that is used to separate concerns in a microservices architecture.
The sidecar pattern enables offloading the processing of some kind to a separate module that gets deployed along with the main service component.
The sidecar pattern is sometimes referred to as a decomposition pattern.
Fundamentally, in microservices architecture, there are several things like logging, configuration, tracing, messaging, etc…are very common modules that we might need to include in each service. We may re-write those lines of code in every needed service. That leads to multiple issues such as
- To change the current implementation, we must make changes in all related service
- Hard to scale up or scale down that specified module
By using the sidecar pattern, it is easy to eliminate the problem by removing redundant code across services and creating separate modules or services. This pattern also helps to enable sharing those modules as a generic component across multiple services so that it is reusable.
1 – Concept
Let’s consider, we have three microservices. All three services have their own business that needs to write logs.
We now add our first sidecar called Logging to each service. Now Logging is part of each service that is responsible for writing the log with its own configuration and implementation. And as a result, we are getting the benefits of the sidecar everywhere while not writing code in each service.
Similarly, we’ve added another sidecar called Configuration to Student and Payment microservices but Course microservice since the Course service does not need this feature.
The benefit is that you pick a sidecar and decide which services you want to apply. Also how much that sidecar shall be scaled based on the number of using services.
As long as your sidecar is written as a module, you can apply it anywhere. It reduces complexity and redundancy in code by abstracting the common infrastructure-related functionalities to a different layer.
2 – Code example
Now let’s have another sample in the code.
We now have three microservices called School, Bank, Tax. The requirement is they all have a calculator to calculate spent money, whilst only Bank and Tax microservices should have a Currency module to exchange the money.
Without a sidecar, the code to calculate total and currency are duplicated.
With the sidecar pattern, those modules are decomposed into the sidecar and be part of the Microservice.
We will have two levels of implementation. Sidecar as a common library and Sidecar as a Service.
Sidecar as a common library
We will create a library project and put two modules into that. This applies to simple plug-and-play modules which do not accommodate complex functionality and scaling.
Sidecar as a Service
We implement the Calculator and CurrencyExchange as two Microservices. Then, we might have a class library that wraps up the call to those services ( REST API calls ). Finally, we plug that wrapped library as a sidecar to each service that we need the functionality.
This is useful when we need to scale up a specified module. For example, the calculator needs to scale up to three instances that serve two more services. This code snippet is kept simple. In fact, the implementation of Calculator and CurrencyExchange might be more complex and thus need to scale into multiple instances.
The detailed implementation of this approach can be downloaded below