Microservices smells

Smells


Cyclic Dependency:
A cyclic chain of calls between microservices exists.

Inappropriate Service Intimacy:
The microservice keeps on connecting to private data from other services instead of dealing with its own data.

Microservice Greedy:
Microservices with very limited functionalities

Not Having an API Gateway:
Microservices communicate directly with each other.In the worst case, the service consumers also communicate directly with each microservice.

Wrong Cuts:
Microservices are split on the basis of technical layers instead of business capabilities.

Mega-Service:
A service that is responsible for many functionalities.

Leak of Service Abstraction:
Designing service interfaces for generic purposes and not specifically for each service.

Bottleneck Service:
A service that is being used by too many consumers and therefore becomes a bottleneck and single point of failure.

Chatty Service:
A high number of operations is required to complete one abstraction.

Low Cohesive Operations:
A service that provides many low cohesive operations that are not really related to each other.

Scattered Parasitic Functionality:
Multiple services are responsible for the same concern.

Service Chain:
A chain of service calls fulfills common functionality.



Refactoring techniques


Encapsulate Responsibility

Encapsulate Responsibility is a technique that is result of adaptation of Encapsulate Method and Encapsulate Field. The main goal of the refactoring is to hide method and corresponding data of the service.
Mechanics:
  1. Add API method that will provide better abstraction to use service's responsibility to encapsulate other methods.
  2. Use hidden methods in the new method.
  3. Change references from previous methods to the new one. If necessary, change the way it is used.
  4. Remove unused API invocations.
  5. In the API Gateway, substitute invocations of set of hidden methods with the new method invocation.
Example:



Move Responsibility

Move Responsibility is an adaptation of Move Method, Move Class and Move Field techniques. With this refactoring it is intended to distribute responsibilities in a microservices system properly.
Mechanics:
  1. Examine all features used by the source method that are defined on the source service. Consider whether they also should be moved.
  2. Declare the method in the target service.
  3. Move the data to the target service if needed.
  4. Copy the code from the source method to the target. Adjust the method to make it work within the new service.
  5. Turn the source method into a delegating method.
  6. Move the data from the database of the source service to the target one.
  7. Remove the source method or retain it as a delegating method.
  8. Replace references from API method to newly created one in other services in the system and in the API Gateway.
Example:



Introduce API Gateway

Introduce API Gateway is an adaptation of Introducing a Dependency Graph Facade and Hide Delegate. The main intention is to hide complexity of using the system - several services in combination - behind one single entry-point service. It is refactoring towards the pattern API Gateway.
Mechanics:
  1. Create gateway service.
  2. Use Encapsulate responsibility (described earlier) for methods of each service that should not be directly available to clients.
  3. Use Move Responsibility (described earlier) for the newly created methods and all the methods that should be public for external clients.
Example:

Inline Service

Inline Service is an adaptation of Inline Class. Its main goal is to change the scope of services - when all the responsibilities of source service are moved to absorbing service.
Mechanics:
  1. Declare the api methods of the source service onto the absorbing service. Delegate all the methods to the source service.
  2. Change all references from the source service to the absorbing service in the system.
  3. Redirect calls in the API Gateway from the source service to the absorbing service.
  4. Use Move Responsibility technique (presented earlier) to move features from the source service to the absorbing service.
Example:

Extract Service

Extract Service is an adaptation of Extract Class. The main intention of the refactoring is to extract part of responsibilities from source service into the new extracted service.
Mechanics:
  1. Create a new service for responsibilities to extract.
  2. If the responsibilities of the old service no longer match service's name, rename the old service.
  3. Use Move Responsibility (described earlier) on each responsibility.
  4. Review and refactor the interfaces of the source and the extracted services.
  5. Change links in the API Gateway from the old service to the extracted one.
Example:


Remove Middle Service

Remove Middle Service is an adaptation of Remove Middle Man. The main intention is to get rid of unnecessary delegation and use the service directly.
Mechanics:
  1. Move API method from middle service that is provided to use delegate to delegate service itself.
  2. For each client using delegate directly replace calls to newly moved API method.
  3. For each client using middle service change service reference to use delegate.
  4. Combine old API method of delegate with the new method.
  5. Remove old API method from the middle service.
Example:

Replace Parameter with Explicit API Method

Replace Parameter with Explicit API Method is an adaptation of Replace Parameter with Explicit Method. The main goal of the refactoring is to make the interface of service more specific for a client.
Mechanics:
  1. Create an explicit API method for each value of the refactored API method's parameter.
  2. For each leg of the conditional, call the appropriate new method.
  3. Replace each caller of the conditional method with a call to the appropriate new API method.
  4. Replace calls of the conditional method in API gateway with a call to the appropriate newly-created API method.
  5. Remove the conditional method.
Example:


Require Data for API Method

Require Data for API Method is an adaptation of Introduce Parameter Object, Move Accumulation to Collecting Parameter and Apply ISP to Make Client-Specific Calls. The refactoring helps to manage responsibilities by removing business logic code from service that is not responsible for it and make it accept the data that is required for service to work.
Mechanics:
  1. Create a parameterized method that can be substituted for each method under refactoring.
  2. Replace one old method with a call to the new method with appropriate parameters across services in the system.
  3. Repeat for all the methods under control, testing after each one.
  4. Redirect calls in the API Gateway from the old methods to the new method with appropriate parameters.
Example:

No comments: