Service Cut by Data Entities and Consistency Needs
Context
Microservices are in use or are planned to be adopted. The service cut is being planned or reconsidered. A domain analysis (e.g. via domain driven design) showed that your domain is comparatively simple and does not contain subdomains.
Problem
- A bad service cut might lead to losing the benefits of doing microservices or to high refactoring costs later on.
Solution
Group your identified domain entities and assign them to a microservices governing that group of data entities. This approach can be used to group data that require strong consistency within their grouping as strong consistency can only be guaranteed within a microservices.
Microservices are only allowed to write on data entities they govern. They can get copies of data governed by other microservices, but they cannot manipulate the original data. This results in a clear responsibility for each data entity.
A data-driven approach might feel most comfortable as software engineers are used to think in data entities and use structural design in order divide and conquer software design. However, this approach is likely to produce a design with higher coupling leading to a loss of independence of microservices and their teams. Based on L31, we advice to only use this data-driven approach in projects with a simple domain that does not contain subdomains.
Maturity
Proposed, requires evaluation.
Sources of Evidence
L3:
- Context: example project (Backtory)
- Domain was not complex => based on domain entities
L4:
- As part of single-responsibility cut
- might be (among others) the responsibility for serving a particular resource or resource representation
- like a user, article, risk (in insurance)....
L12:
- Context: Example system
- Service cut based on domain entities
- since domain was not very complex
- cohesive entities into one service
- only one to create and update the entity
- other services can have copies (e.g. caching)
L31:
- Context: migration patterns
- Pattern MP4: Decompose the monolith based on data ownership
- Context:
- system with non-complex domain
- At least one of the following applies
- complexity => comprehensibility of source code low
- different non-functional requirements for different parts of the system
- changes lead to whole redeployment although independent release cycles desired
- Problem
- How to divide into slammer chunks? How big?
- Solution
- Decompose based on data ownership
- Group data entities => should have unique owner
- grouped data + business logic => into one service
- entity can only be modified by its owner (service)
- other services only can have copies
- be aware of staleness
- need to synchronize
- further decomposition can happen based on non-functional requirements or change frequency
- Challenges
- suitable if domain is not complex, data entities can be grouped easily
- in large domain with multiple subdomains => confusing, time consuming, may lead to inappropriate decomposition
- Context:
- Pattern evaluation
- MP4 found equally in all 3 case studies
- lowest number of occurrences compared to MP3 (DDD) and MP5 (code dependency to service call)
L34:
- Microservice should be large enough to ensure data consistency
LN39:
- Context: Table 2 lists approaches for service cutting
- Approach 10: bottom-up, data-driven approach
Interview A:
- At first they did not do well
- did what most did: take libraries and classes and put heading "microservice" over it
- first step: refactor monolith with REST API calls to itself => "broke their own back"
Interview B:
- Thinking of entities results in data-flow majorly in focus when speaking about flows
- Example: data forms with steps
- some fields disabled in step x, ...
- suggests I'm in a flow, but it is a huge input mask
- if I do that with microservices: need to send around data, sometimes this, sometimes that
- => probably not a single workflow / use-case that can be processed within one service, but includes automatically other services
- => dependencies (bad)
Interview D:
- What most people do: function decomposition / ER diagrams and data-driven decomposition
- take their lead entities from data model and append "service"
- => "that is my bounded context"
- e.g. customer context, order context, product context
- order context always needs to grab into product context
- take their lead entities from data model and append "service"
- Hard to change this way of thinking
- shaped by structured design principles, as divide and conquer
- call-stack based decomposition => everything calls everything => everything has to run in order to work
- strong coupling: the thing above doesn't work if the things below don't work
- leads to many project failures
Interview F:
- Strong consistency only within a microservice instance (not a microservice)
- need to find strategies to cope with that
- among others: put things that nneed to be consistent into one service
- if you overdo it: end up with monolith
- => decide where need for strong consistency is not really there