December 04, 2019

Part 12: Microservices (Decomposition)

How to decompose an application into services?
1). Decompose by business capability pattern: It define services corresponding to business capabilities
2). Decompose by subdomain pattern: It define services corresponding to DDD subdomains
3). Self-contained Service pattern: The design services to handle synchronous requests without waiting for other services to respond
4). Service per team

Pattern: Decompose By Business Capability and Decompose by Subdomain
  • A service must be small enough to be developed by a small team and to be easily tested. 
  • A useful guideline from object-oriented design (OOD) is the Single Responsibility Principle, which defines a responsibility of a class as a reason to change, and states that a class should only have one reason to change.
  • We need to decompose the application in such a way so that most new and changed requirements only affect a single service. That is because changes that affect multiple services requires coordination across multiple teams, which in turn slows down development. 
  • Common Closure Principle (CCP), which is another useful principle from OOD is the Common Closure Principle (CCP), states that classes that change for the same reason should be in the same package.
While decomposing services by Business Capability or by Decompose by Subdomain we need to make sure:
  • Services must be cohesive, a service should implement a small set of strongly related functions.
  • Services must be loosely coupled, the implementation can be changed without affecting clients
  • Services must conform to the Common Closure Principle. The classes that change together should be packaged together, this will ensure that each change affect only one service
  • A service should be testable
  • Each service be small enough to be developed by a small team (often called as a 'two pizza”' team, because it has 6-10 team members).
  • A team must be able to develop and deploy their services with minimal collaboration with other teams.
  • Each team that owns one or more services must be autonomous. 
Solution to decompose services by Business Capability
We should first define services corresponding to business capabilities. FYI, a business capability is a concept from business architecture modelling. It is something that a business does in order to generate value. A business capability often corresponds to a business object.

Solution to decompose services by Subdomain
We need to define services corresponding to Domain-Driven Design (DDD) sub-domains. FYI, DDD refers to the application’s problem space as the domain. A domain is consists of multiple subdomains. Each subdomain corresponds to a different part of the business.

Subdomains can be classified as follows:
  • Core: key differentiator for the business and the most valuable part of the application
  • Supporting: related to what the business does but not a differentiator. These can be implemented in-house or outsourced.
  • Generic: not specific to the business and are ideally implemented using off the shelf software
Self-Contained Service
Let's say you have a restaurant, a customer come and orders a pizza (customer service). Then the person who took the pizza will take the payment and ask the cook to prepare a pizza (kitchen service). A cook might delegate the work to someone else in the kitchen (Chef service).

This is a synchronous flow, which has a drawback that it reduces availability. That’s because if any of the customer Sevice’s collaborators are unavailable, it will not be able to create the order and must return an error to the customer.

We need to make sure that the Customer Service always respond to a POST /orders request even when one of the other services is unavailable.

While decomposing services by Self-contained service we need to keep in mind:
A service can retry a request to a failed collaborator but this increases response time.
All the operations are typically required to be highly available with a low response time
The availability of an operation is the product of the availabilities of the services that are invoked while handling a request

Solution to decompose services by Self-contained service:
Design a service so that it can respond to a synchronous request without waiting for the response from any other service. We can make services self-contained by merging the similar services into one rather than a separate services. We could, for example, merge the Kitchen Service and Chef Service.

We can also fix this by eliminating all synchronous communication between the customer Service and its collaborators by using the CQRS (Command Query Responsibility Segregation) and Saga patterns. The Order Service can use the CQRS pattern to maintain a replica of the restaurant menu’s and there by eliminate the need to synchronously fetch data from the Restaurant Service.

It can validate the order asynchronously by using the Saga pattern. The Customer Service creates an Order in a PENDING state and sends back a response to the POST /order. It then completes the creation of the order by communicating asynchronously with the other services.

-K Himaanshu Shuklaa..

No comments:

Post a Comment