May be the first question should be: what would help me decide whether my Microservice should contain an entire bounded context possibly with several aggregates, or should it rather contain only one aggregate?
If the Microservice contains several aggregates, then another question rises in my mind: shall the Microservice have several transactional boundaries (one per aggregate) or shall the Microservice have only one transaction boundary (the bounded context)?
Maybe, the answer to these questions is: it depends. But I'd like to have some rationale to make the right decisions.
I've tried to implement an experimental Microservice that implements a bounded context made of 3 aggregates and one transactional boundary per aggregate, and I've faced some pain points:
- Eventual consistency within the Microservice itself
- Atomic update of the aggregates and publication of domain events within the Microservice in a resilient way
- Deciding whether all the domain events shall be published externally (to other Microservices) or only some of them
- Deciding whether the domain events shall be published in the form of integration events in order to preserve the purity of the domain model
Then I've envisioned the possibility to split the Microservice into several Microservices, one per aggregate:
- It gets more natural to publish all domain events (no clear need to make a difference between domain events and integration events)
- The internal complexity of the Microservice is reduced
I've not managed to find some documentation on this subject to guide me in the decision making.
Edit:
Would it make sense to consider that the bounded context could be a set of Microservices working together as partners, and where each Microservice would encapsulate one and only one aggregate with its own scaling strategy?
Then, each Microservice would have one and only one reason to change: the aggregate.