Microservice Design Patterns
Tags: microservices, designpatterns
Published: 2023-08-27 12:01:33

##What is microservice?

Microservice is a software architecture pattern used to design and develop applications as a collection of **small**, **loosely coupled**, and **independent services**. In this approach, an application is divided into multiple individual services, each responsible for **performing a specific functionality** or feature.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9x9iv72mh5u3w4mho8s2.png)

##Who Invented Microservices?
There are numerous claims as to the origin of the term microservices

As early as 2005, **Peter Rodger** introduced the term "**Micro-Web-Services**" during a presentation at the Web Services Edge conference.

Microservices, as a software architecture concept, did not have a single inventor. Instead, the concept of building applications using small, independent services has evolved over time, driven by the need for scalable, flexible, and maintainable software systems.

The term "microservices" gained popularity in the early 2010s.

##Key Influencers of Microservices

The microservice architectural pattern is influenced by various architectural styles and practices. 
Some key influences include:

**1. Service-Oriented Architecture (SOA):** SOA is an architectural style that dates back to the late 1990s. It promoted the idea of building applications as a **collection of loosely coupled services**. While SOA and microservices share some similarities, microservices are considered a more granular and lightweight approach.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/brzdbf4nppthl99ccg1j.png)


**2. Domain-Driven Design (DDD):** Introduced by Eric Evans in his book "Domain-Driven Design: Tackling Complexity in the Heart of Software" in 2003, DDD focuses on modeling software systems based on the business domain. DDD principles have influenced how microservices are often organized around specific business domains.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oqb2khx35g6wa8puifja.png)


**3. Continuous Delivery:** The rise of continuous delivery and DevOps practices in the mid-2000s encouraged a more agile and automated approach to software development and deployment. These practices paved the way for the idea of developing and deploying small, independent services.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gjul4gxt9qgbuak45i6r.png)


**4. Representational State Transfer (REST):** RESTful architecture, proposed by Roy Fielding in his 2000 doctoral dissertation, provided principles for designing networked applications. RESTful APIs are commonly used in microservices to enable communication between services.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/snmtwcxxebt519545l2a.png)

##Characteristics of Microservices
**1. Modularity:** Each service represents a distinct and self-contained module, which can be developed, deployed, and scaled independently of other services.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c7u6crrfn7dsgpgbm3xs.png)

**2. Independence:** Microservices can be written in different programming languages and use various technologies, making it easier to choose the best-suited tools for each specific task.

**3. Decentralization:** Unlike traditional monolithic architectures, microservices promote a decentralized approach, where each service handles its own data and business logic.

**4. Interoperability:** Communication between microservices usually takes place via well-defined APIs, making it easier for them to work together and interact with one another.

**5. Scalability:** Since each service operates independently, it allows for better scalability and performance optimization. You can scale only the services that require more resources, rather than scaling the entire application.

**6. Resilience:** Microservices can improve the resilience of an application since the failure of one service doesn't necessarily bring down the entire system. Fault isolation allows other services to continue functioning.

**7. Continuous Delivery/ Deployment:** Microservices facilitate continuous deployment and integration since each service can be developed and deployed independently of others.

However, implementing microservices also introduces some challenges, such as managing distributed systems, handling communication between services, and dealing with potential data consistency issues.

Microservices are particularly popular in modern software development, especially in cloud-based and large-scale applications, as they offer greater flexibility, scalability, and the ability to adapt to changing business requirements.


##Different problems have different solutions, same way there are different microservices patterns which suits for different business requirements. 

While designing applications based on Microservices architectural pattern, we need to think about, what problem we are trying to solve and what is our business need.

**1. Strangler Pattern:** Gradually migrates functionality from a monolithic system to microservices by incrementally replacing parts of the monolith with microservices. 

**2. Circuit Breaker:** Helps prevent cascading failures by monitoring the health of a downstream service and opening the circuit if the service is unavailable or experiencing issues.

**3. Domain-Driven Design (DDD):** Aligns the architecture with the domain model, focusing on the business logic and modeling complex processes using bounded contexts and aggregates. 

**4. CQRS (Command Query Responsibility Segregation):** Separates read and write operations into distinct models, optimizing data storage and retrieval for specific use cases.

**5. API Gateway:** Provides a single-entry point for clients to access multiple microservices. It can handle request routing, load balancing, caching, and authentication.

**6. Backends for Frontends (BFF):** Tailors individual backends specifically for frontend clients, providing a better fit for each client's requirements.

**7. Bulkhead:** Isolates parts of the system, such as thread pools or resources, to prevent failures in one component from affecting others, thus improving system resilience.

**8. Saga Pattern:** Manages distributed transactions in microservices by breaking them down into smaller, manageable steps with compensating actions for possible failures.

**9. Event Sourcing:** Stores the state of a system as a sequence of events, enabling easy replication, auditing, and rebuilding of system state.

**10. Service Registry and Discovery:** Enables dynamic service discovery by using a central service registry where microservices register themselves, and clients can discover services at runtime.

**11. Sidecar Pattern:** Attaches an additional service (the sidecar) to the main service to provide specific functionalities such as logging, monitoring, or security.

**12. Gateway Aggregation:** Aggregates data from multiple microservices into a single response, reducing the number of client requests and enhancing performance.

**13. Database Per Service:** Each microservice has its own dedicated database, ensuring loose coupling and independence between services' data.

**14. Asynchronous Messaging:** Uses message queues or event buses to enable communication and data exchange between microservices in an asynchronous and decoupled manner.



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xzd9vr3fmu3rmugyqnd0.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p43shhhso7u8fpjq0fhm.png)

Let's understand with example.

Let's assume Jack and Jill have a restaurant, they cook really awesome burgers. They have small business, so every take care of all processes needed for business. 
Same as monolith, each module is responsibility of monolith 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ne10yow6thxs82mb03bl.png)

As they are awesome cook, they are getting more and more customers. As they need to serve many customers, they are serving slow.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e66qfx6wtdtr0wlw2npa.png)

So they need hired John to help.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dkwhdieocnpyp0ikkgyf.png)

With increasing customers John also needs help to serve faster. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bplm43r3gyj4ld5kbxcp.png)

Now with these distributed responsibility 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j9b73gw0qyrq1m6royjn.png)

This also demonstrate how we can independently scale the different systems. 

##CQRS 
Command Query Responsibility Segregation
**Command**– To manipulate the data
**Query**– To fetch the data

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/whdbtnuf9c2i1xcur12i.png)

In above example,
When we go to any restaurant, and ask for pizza, chief make a dough, make a base, add toppings or some ingredients and bake it. 
But when we ask for menu, it's very quick, whatever is there, printed on a paper we get it as result. Chief is not involved here.
Same way if we have read and write databases separate, we can achieve good database performance, faster reads and much more. 



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w1bftv8lx79uk5kc49f1.png)

Above is an example of single database for read and write operations

Let's see the distributed responsibility


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fqzqi8ohi7jg08etlgrk.png)