Service Cut by Functional Proximity
Context
Microservices are in use or are planned to be adopted. The service cut is being planned or reconsidered.
Problem
- A bad service cut might lead to losing the benefits of doing microservices or to high refactoring costs later on.
Solution
Use functional proximity and the single responsibility principle to drive the microservice cut.
The single responsibility principle can mean two things:
- (a) a component should do one thing and one thing only, and
- (b) a component should compile elements that change for the same reason. Especially the second meaning aligns well with the goal of removing coupling between microservices to enable independent development cycles.
If migrating from a monolith, you can examine your version control system history which code fragments were changed together in the path and use this metric as guidance for a service cut. You can combine this metric with other service cutting techniques.
We did not find further refined guidelines or processes in order to come up with a concrete service cut based on the single responsibility principle. We assume that predominantly ad-hoc processes are applied leading ito results that are heavily dependent on the experience of the architects.
Maturity
Proposed, requires evaluation.
Sources of Evidence
L4:
- Single responsibility
- only a single reason to change / be replaced
- does one thing only
- Could be about a functional requirement, or a non-functional requirement, or a cross-functional requirement
- Examples
- queue processor (read message, perform small piece of business logic, pass it on)
- responsibility for serving a particular resource or resource representation like a user, article, risk in insurance
- very focused and small that performs task on its own
L27:
- Extraction strategy: logical coupling strategy
- Single responsibility principle => gather elements that change for the same reason
- module boundaries are enforced by microservices
- case of change: only need to locate module, only to understand the confined module
- => cluster files changed together
- Evaluation
- team size reduction median at ~0.25
- average domain redundancy at ~0.3
- was combined with other metrics as well
L31:
- New service instead of sharing code to share functionality
- either isolated new service, or part of the dependent service
- different scalability needs also a good reason to spawn new service instead of sharing library
L38:
- Often single responsibility principle applied for microservices
- e.g. solve one business need nicely
L41:
- Example system
- Consider case by case if functionality results in new service or not
- business functionality isolated and big enough, or shared between other business functionalities => new service
- some cases: include in existing service, only later moved to their own separate service
- e.g. functionality too big or equally required by multiple services
- (+) approach hindered the possibility of a reimplementation of old system as distributed monolith
L54:
- Example system
- Shopping system into catalog, recommendation, ratings, and user account services
- catalog service might contain funcatilan parts including catalogs of bags, cloths, music or even music
- => independence of service and function by their own
- => erases reusability of services, as recommender service might only need to interact with the movies catalogue
LN39:
- Reference to book "Working Effectively with Legacy Code": separate portions of independent code => fits "loosely coupled and strongly cohesive" microservices
- Table 2:
- Decomposition by interface analysis: cluster interface specs accoording to semantic similarity
LN43:
- Each microservice complies with single responsibility principle
- focused on one functionality
- boundaries makes it clear where code changes should go
LM43:
- Context: SLR findings about microservices in DevOps
- S33 recommends MVC pattern for decomposition in terms of business ScriptProcessorNode, functionalities and responsibilities
- interpretation: not clear what MVC decomposition here means, but seems to refer to grouping same functionality into one microservice
LM45:
- Context: interviews and insights from multiple cases on technologies and sw quality in MSA
- C6-10
- functional or feature-oriented decomposition
- DDD not used due its perceived complexity
LM47:
- Context: SLR with tactics to achieve quality attributes
- Tactic to reduce logical coupling
- use single responsibility principle for decomposition
- software elements changing for the same reason should be gathered
- to enforce strong module boundaries
- static code analysis can be used
Interview C:
- "micro" might be misleading
- does not mean code size or platform size
- means amount of functionality
- back in the 90s: component ideally serves a function / an functional area