"Macro benefits with Microservices" using design pattern approach - Part 1
‘Microservices’ portrays a specific method of designing software applications, as a collection of small autonomously deployable services formed around a business domain. Each of these services is self-contained and implements a single business capability. These loosely coupled services are compatible to work across hybrid environments.
In other words, microservice is a software design approach is a practical example of "Law of Demeter"
MicroService Principles
It is important to understand the principle used to design Microservice Architecture
Microservice Design Patterns
Looking at the above principles, we can see that there can be several challenges and issues while building your solution making it and go live. Those challenges can be tackled beforehand if one understands how to use the correct and matching design pattern while designing based on the required use cases.
Broadly, the design patterns for microservices are divided into 5 categories as shown in the image below:
Decomposition Patterns
- Decompose by Business Capability - It talks about making microservices loosely coupled with implementing the single responsibility principle. Microservices are decomposed based on business functions. Example: Order service manages orders, catalog service manages listed items in an e-commerce application.
- Decompose by subdomains - It talks about further decomposing the business functions in subdomains, corresponding different parts of the business. Example: Catalog service can be divided into inventory management, restriction management.
- Strangler - It talks about the pattern where the legacy code (monolithic) and the newly factored code (microservices) co-exists as two separate applications living side by side in the same URI space. It is managed where traffic is initially 80% on the legacy and 20% on the new one. But later newly factored application strangles the old/legacy one. Thus it has 3 steps: Transform, Coexist & Eliminate.
- Bulkhead - It talks about the pattern where critical resources are isolated, such as connection pool, memory, and CPU, for each workload or service. By using bulkheads, a single workload (or service) can’t consume all of the resources, starving others. This pattern increases the resiliency of the system by preventing cascading failures caused by one service.
- Sidecar - It talks about the pattern where helper components of an application are kept as a separate container or process to provide isolation and encapsulation. As it's names suggest, it represents a sidecar application associated with a parent application, the same as a sidecar is attached to a motorcycle.
Integration Patterns
- Aggregator Pattern - It talks about how we can aggregate the data from different services and then send the final response to the consumer. It is based on DRY Principle, which means we can abstract the business logic into 2 -3 microservices, and later we can aggregate that business logic into one specific service. The benefit is multiple scalable microservices can simultaneously provide the response and the aggregator can collate those into a final response.
- API Gateway Pattern - Microservices design is not a rosy picture, but it comes with its own set of challenges. Like how can we request information from multiple microservices, how to handle multiple protocol requests, how to transform data according to a consumer requirement out of a reusable microservices. The solution to these kinds of problems is API Gateway Pattern, and apart from that, it provides other benefits as well. It acts as an entry point to forward the clients to appropriate microservices, and can create a fine grain response based on consumer needs. Other benefits include: it can offload authentication responsibility, can convert one type of protocol to another type. It can act as a proxy allowing features such as security. It's responsible for request routing mapping as well.
- Chained Microservice Pattern - This pattern basically talks about producing a single output which is the combination of chained outputs from various microservices. If we have 3 services lined up in a chain, the request is first catered by microservice-1, then communicate with microservice-2, then microservice-3, and then the final output. All these use HTTP synchronous request or response for messaging. Also, the response may vary from one service to another.
- Branch Pattern - It is a combination of Aggregator & Chained microservice design pattern. As the name says, it's all about branching, where we can simultaneously process the request and responses from 2 or more independent microservices. Unlike the chained design patter, the request is not passed in sequence but is passed to multiple microservices in the chain and that too simultaneously.
- Client-Side UI Composition Pattern - It talks about extending the decomposing UI or front end thick client into micro frontends. A composite UI is precisely generated and composed by the microservices themselves. The key is that you have client UI components (TypeScript classes, for example) based on templates, and the data-shaping-UI ViewModel for those templates comes from each microservice. Each of those UI composition microservices would be similar to a small API Gateway. But in this case, each one is responsible for a small UI area.
In the next post, let's cover the remaining design patterns for microservice architecture.
Very informative!!
Nice and Apt Article. Thanks for sharing. Good refresher!!!
Thanks for posting such detailed information on MS 👍.
Good summarised view...
Nicely covered, Thanks for sharing