Service Cut by Use-Case
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 seclusiveness of use-cases from user perspective as metric for the microservice cut. A use-case (or at least its default path) should be handled within one microservice. If this principle is applied generally in your architecture, you can limit the number of hops between services as a convention.
If data of other services is required to serve the use-case the data should be replicated in an out-of-band manner. As an example, in an e-commerce platform the default path of the use-case of a usual checkout process would include the default payment, the default delivery address, and so on. However, if we deviate from the default path, for example if we want to specify another delivery address, we can use other services as well to cope with that. Fetch the list of all delivery addresses for the user, and let them choose. As next step this information has to be conveyed to the original service, either again by data replication, by fetching it, or by providing it with the user's request.
This cutting technique leads to better decoupled microservices without the need for transactions. Since use-cases are processed within one microservice we avoid network calls that would lead to performance drawbacks. The out-of-band data replication (if done right) presents us the advantage of not thinking too much about network failures and how to handle them, however, with the price of potentially dealing with data that is not up-to-date (yet) due to eventual consistency guarantees.
Maturity
Proposed, requires evaluation.
Sources of Evidence
L34:
- "It can be noted that μServices emphasize isolation in a way that a particular process and user interaction operate in the scope of a particular service."
LN39:
- List approach 5 based on use cases (user representations)
- List approach 3 based on use cases (UML) => security
LN43:
- one method for decompositions: find seams from existing software
- seam = part of isolated and stand-alone code
- requires knowledge about business use cases
Interview B:
- Danger of thinking in entities and flows => use case include many services => big dependency
- Example: checkout process in web shop
- flow spans multiple services collecting, manipulating, and saving data
- Order service, customer service ,inventory service, address service, payment service...
- flow spans multiple services collecting, manipulating, and saving data
- => need for transactions
- complex, esp in failure cases
- dependencies
- Example: checkout process in web shop
- Recommendation: cut service so that it maps to use cases
- Example: checkout process in web shop
- try to capture at least default path within one service
- default path example: checkout -> default payment -> default delivery address,
- data is already replicated to the service!
- positive case: work with only one service although it is a flow
- deviation from standard: e.g. other delivery address
- list of delivery address shown + let choose
- how does that information get to our service then?
- replicate, or fetch => need for pattern here
- need for overarching flows kept small
- Example: checkout process in web shop
Interview D:
- cut services in a way that don't allow further service calls
- => self-contained systems / independent service architecture
- request always is processed within only one service
- that is domain coupling
- topic since 60 years but still not solved well
- Between services only batch communication
- data flow in both directions
- timely decoupled, out of band
- that compensates for most usual failure sources
- omission failure, timing failure, latency, non-availability,... are handled that way
- Especially works well for enterprise companies
- not "micro", maybe a little bigger - but doesn't matter
Interview E:
- Context: when use backend for frontend pattern
- If good vertical cut => not necessary
- talking with one microservice only anyway
- Otherwise: use the backend for frontend pattern
- to avoid unnecessary coupling, dependencies, performance reduction
Interview F:
- Context: cutting by departments and their responsibilities
- you don't want to be forwarded to other departments all the time
- but still, there are dependencies to other departments
- => maybe as good indication if communication should be sync or async