Last Updated on September 22, 2023 by KnownSense
The aim of Domain-driven Cohesion in Microservices is to help us tightly scope our microservices so that they represent a specific business domain within our organization in terms of the data and the functionality they provide. The cohesion part of this principle is just there to emphasize the fact that each individual microservice must be tightly scoped and focused around that specific area and there’s no distracting data or functionality which is not related to that specific area that the microservice represents. So if you’re concerned about how to size individual microservices, this Domain-driven Cohesion design principle will guide you.
Business Domain
If you’re starting from scratch with a new architecture, the first thing to do is identify the core business domains within your organization. As a starting point, you initially just draft individual microservices to represent each one of these areas in terms of the data and the functionality within that specific business domain area. Then after this starting point, we can start reviewing each microservice to see if there’s any advantages of further splitting that microservice into other microservices. For example, in the Account service, we realize that the Expenses functionality has a number of long‑running tasks which might impede the overall performance of the account service, and therefore, we make a decision to improve performance we’re going to separate that functionality out into a separate Expenses microservice. So performance is one reason for splitting your microservice.
The frequency of change faced by a specific data or functionality can be another reason for further splitting your microservice. For example, our Product microservice features data and functionality related to warranties, which is always changing. To mitigate the risk of change, we’re going to separate the warranty’s data and functionality out into a separate microservice.
Improving resiliency and availability is also another valid reason for considering further splitting your microservices. Another example of this is when we might be using an external API from a third party which is unreliable. For example, our Order’s microservice might use an external API for postal calculations, which is unreliable and always throwing up errors, so instead of having that risk within our Order’s microservice, we instead create a new microservice called Postage which handles all the inconsistent results from our unreliable third‑party API.
Another valid reason might be that within that specific business domain there is actually a subdomain, a sublanguage, a subset of data and functionality. For example, in our Promotion’s microservice, we have a lot of data and functionality related to promotions, but there’s also a lot of data related to marketing stats, which has its own language and own functionality, and it makes more sense to actually separate this out into a separate microservice.
Focused Cohesion
In the above scenario Promotion service was an example of a service that lacked focused cohesion. It basically had two reasons for changing the Promotion’s data and functionality and the Marketing Stats data and functionality.By splitting the subdomains out, we now have two microservices with much improved focused cohesion where all the concepts and the core concepts are tightly related and tightly scoped. So the key takeaway here is don’t be afraid to further split your microservices.
On the other hand, don’t also be afraid to merge two separate microservices together if it makes the data and the functionality more accessible and more convenient. For example, if you have a service which has data and functionality, which is only ever used by one other microservice, it might make sense to actually merge those services together.
Bounded Context
If you’re looking for a more methodical technique to scope your individual microservices, one technique taken from domain‑driven development is the idea of identifying bounded context. This is a collaborative approach where someone like a product owner or a product manager brings together the technical team and the domain team, i.e. business team related to specific parts of your organization.
The idea is you work together to identify core concepts within your software, within your organization. Then around these core concepts, you group together related concepts, and these concepts basically represent specific pieces of data and functionality within your organization or your software. Once you’ve exhausted the list of related concepts to the core concept, you’ve basically formed a bounded context. Basically, this bounded context is the starting point for one of your microservices. As you’re identifying these concepts, there will be some concepts which are kind of related to the core concept, but not quite, and therefore, they fall outside the boundary. it’s these concepts that fall outside the boundary will actually form their own core concepts, which will later on develop into their own bounded context. You basically repeat this process of identifying core concepts and related concepts and identifying what concepts actually slightly fall outside the boundary and therefore should form their own core concept and therefore their own bounded context, and eventually, you’ll basically develop the blueprint for your initial microservices.
The way above described this process can sound very clinical, but the key thing to remember here is you’ll have both the business team and the technical team discussing these concepts together, so you’ll have two different languages coming together to form one language. During this process, you’ll find there’s so much hidden knowledge from each side of the business, the business side and the technical side, that you’ll end up designing a much better system.
Event Storming
If you want something that’s even more collaborative and methodical in terms of scoping your microservices and designing your overall microservices architecture, I can’t highly recommend event storming enough as it highly complements the idea of identifying bounded contexts by plotting events along the timeline and then rearranging those events around aggregates, which are basically similar to your core concepts, and then those aggregates basically form your bounded context, which become your microservices. The amazing thing about event storming is not only does it scope and identify individual microservices, but it also identifies the communication between them, more or less designing your entire microservices architecture at a very high level.
Because of the involvement of both the domain team and the technical team and the focus on identifying aggregates, it’s a very effective way of delivering the domain‑driven cohesion principle within your microservices architecture.
Existing Seams and Boundaries
Now the next question is, this all sounds great when you’re starting from scratch, but what if you already have a code base, a large application featuring a lot of code? How do you transition from that code to microservices? The good news is you use the same approach. You identify all the course business domains within your organization, then you identify the code within your code base that’s related to each aspect of your business, and then you identify seams within your code to see where the division within the code is. There will be leakage is between these seams where you’ve got code for a specific business domain being used within another business domain, and using some code refactoring, you can tidy the code up so there’s clear boundaries and seams within the code so that each aspect of the code is related to a specific business domain’s data and functionality. Then each one of these seams and boundaries basically become a bounded context that you can convert into a microservice by extracting the code out. Again, we might further split these microservices up to gain performance reliability or to reduce the risk of change. So the good news is even if you’ve got an existing application, a large application, you can apply the domain‑driven cohesion designed principle to create new microservices which basically extract the code from the original application.
Strangler Application Pattern
The other good news is there is actually a proven methodology that can assist you in transitioning from a large application to microservices using the ideas behind the domain‑driven cohesion design principle, and this methodology is called the strangler application pattern.
Easily Rewritable
Another key point worth mentioning in this section is that when you’re scoping your microservices, ensure that they are easily rewritable. Ensure that the amount of code within each one of your microservices is of a certain size so that it can be rewritten within two to three weeks as this will improve not only your ability to rewrite microservices with newer technologies, but also the team’s ability to learn different microservices that they might be new to.
Conclusion
In summary, we learn how we could make our services so that they have domain‑driven cohesion, where each service represents a specific part of the business in terms of data and functionality and each service has a cohesive focus. We concluded not only does each service need to represent a business domain in terms of data and functionality, but that service also must only have one reason for change, i.e. it must have focused cohesion. We also concluded one way of tightly scoping these microservices is to use a technique of identifying bounded context, bounded context which then become the microservices. And for existing large applications that we want to convert into microservices, we looked at how we could identify existing seams and boundaries that could be identified as bounded context that we could convert into microservices. Then we looked at a microservices scoping technique called event storming, which is complementary to the idea of identifying bounded context, and we briefly saw how it can be used to bring together both the business team and the technical team in order to design our microservices architecture in a collaborative way. And despite having all these scoping techniques, one thing we did emphasize was whatever microservices you come up with, we’ve got to ensure that they’re easily rewritable so that we can easily rewrite them in two to three weeks.
Domain‑driven cohesion in Microservices, promotes modularization, maintainability, and alignment with business goals, making it easier to develop and evolve a complex software system. However, it requires careful domain modeling and collaboration between domain experts and development teams to define and implement the bounded contexts and domain boundaries accurately.