Journal of Distributed Software Engineering, Architecture and Design
Domain Service Design and Patterns
<div class="cs-rating pd-rating" id="pd_rating_holder_1819065_post_1629"></div>
<p class="wp-block-paragraph">Domain services implement core logic for a business domain and are a relied upon by experience and consumer services. Domain services can be self contained and store the business logic and state or rely on an external provider system (translating from a “raw system format” to a “canonical” domain format)</p>
<p class="wp-block-paragraph">In this post we look at some of the types and design patterns for domain services especially around the monolithic-database services and the SOA-type domain services </p>
<p class="wp-block-paragraph">Looking at these types and design patterns should help you and your team identify the type of domain service you are building, recognise some of the constraints in delivering business value and hopefully you can start to balance coupling and cohesion in your services better! </p>
<p class="wp-block-paragraph">This is a longish post, so for those in a hurry – here are the key takeaways from this post </p>
<ol class="wp-block-list"><li>Domain services model core <strong>business domains</strong> vs other types of service oriented architecture which focus on layer, system or no-particular orientation</li><li>Domain services are about not leaking internal context out, so <strong>boundaries are important</strong>. If your service design teams knows about client contexts or clients know about your implementation details then the boundaries are not clear, leading to confused software </li><li>Going too broad with coarse domain services creates challenges with software that is used in multiple contexts leading to poor experience, data quality, change autonomy etc </li><li>Going too fine grained with domain services is a problem too, especially if multiple small services couple to each other and get chatty. This can create a hair-ball (cyclic graph) </li></ol>
<h3 class="wp-block-heading">Domain Services: Wide context</h3>
<p class="wp-block-paragraph">Domain services provide an implementation over the core business functions for a particular domain, for example Order, Shipping, Customer, Identity, Document etc. </p>
<p class="wp-block-paragraph">Domain services provide an API for Commands (create/update) and Queries (Search, Get by ID) using a Domain Model. This model is key as it is the representation of the business model of the domain to external services. The domain model is determined through design processes such as Domain Events or Domain Storytelling using the Domain Driven Design (DDD) technique</p>
<p class="wp-block-paragraph">Domain services also publish Domain Events which are emitted in a domain language and often notify subscribers of a change in the state of a domain object</p>
<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://alok-mishra.com/wp-content/uploads/2021/04/slide1.png"><img src="https://alok-mishra.com/wp-content/uploads/2021/04/slide1.png?w=1024" alt="" class="wp-image-1668" width="659" height="502" /></a><figcaption>A hypothetical C4 context model of a business with a Customer, Experience Channels, Experience Services, Domain Services and Systems </figcaption></figure></div>
<h3 class="wp-block-heading">Commands, Queries, Events for State transfer </h3>
<p class="wp-block-paragraph">Domain services provide APIs for Commands and Queries and emit events called Domain events. These operations manage the state of a domain resource (HATEOS anyone?)</p>
<p class="wp-block-paragraph">Commands on a resource enable the state transition, for example POST, PUT, PATCH. Queries enable the consumers to read the information about the current state, for example GET. Commands on a collection help us to search, add or remove items and Queries on a collection help search and list specific items by an identifier</p>
<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-08-at-10.33.55-pm.png"><img src="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-08-at-10.33.55-pm.png?w=1024" alt="" class="wp-image-1671" width="506" height="417" /></a><figcaption>Domain events are emitted on specific state changes. State transitions are done via operations in the API </figcaption></figure></div>
<p class="wp-block-paragraph">Domain events are emitted on all or specific state changes, for example “OrderCreated”, “OrderSubmitted” or “OrderCancelled” and as you can imagine subscribers for these order domain events would be Shipment Domain service or Payment domain service</p>
<h3 class="wp-block-heading">Types of Domain Services</h3>
<ol class="wp-block-list"><li>Monolithic domain service</li><li>Provider backed domain service </li><li>Provider backed domain service with read-store</li><li>Self-contained domain service</li></ol>
<h5 class="wp-block-heading">Provider backed Domain Services</h5>
<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-08-at-10.33.34-pm.png"><img src="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-08-at-10.33.34-pm.png?w=938" alt="" class="wp-image-1673" width="510" height="556" /></a><figcaption>Provider backed domain service. The state is managed in the external system</figcaption></figure></div>
<h4 class="wp-block-heading">Provider backed domain services with read-store</h4>
<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-08-at-10.41.14-pm.png"><img src="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-08-at-10.41.14-pm.png?w=1024" alt="" class="wp-image-1678" width="539" height="509" /></a><figcaption>Provider backed domain services with read-store. State is in the external system, query can be in the domain service driven by events from external system</figcaption></figure></div>
<h4 class="wp-block-heading">Self-contained domain service</h4>
<p class="wp-block-paragraph">There is no COTs system as the master, this domain service is the master with the business logic</p>
<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-08-at-10.41.20-pm.png"><img src="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-08-at-10.41.20-pm.png?w=1024" alt="" class="wp-image-1676" width="585" height="498" /></a><figcaption>Self-contained Domain services </figcaption></figure></div>
<h4 class="wp-block-heading">Monolithic Domain Service</h4>
<div class="wp-block-image"><figure class="aligncenter size-large"><a href="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-08-at-10.49.12-pm.png"><img src="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-08-at-10.49.12-pm.png?w=1024" alt="" class="wp-image-1680" /></a><figcaption>Monolithic database behind two or more domain services. </figcaption></figure></div>
<h2 class="wp-block-heading">Service Design Patterns</h2>
<p class="wp-block-paragraph">There are 3 core patterns when building domain services</p>
<ol class="wp-block-list"><li>Monolithic Service: Single endpoint, large canonical data model, coupled contexts across different domains (SOA)</li><li>Explicit context, common services : Mono-repo with multiple teams from different domains and contexts in a single common service</li><li>Explicit context, unique service: Micro or Coarse-grained services with multiple contexts owned by the same team for a single domain service</li></ol>
<h4 class="wp-block-heading">Monolithic service</h4>
<figure class="wp-block-image size-large is-resized"><a href="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-08-at-11.01.25-pm.png"><img src="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-08-at-11.01.25-pm.png?w=924" alt="" class="wp-image-1683" width="573" height="186" /></a></figure>
<figure class="wp-block-image size-large is-resized"><a href="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-08-at-11.01.20-pm.png"><img src="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-08-at-11.01.20-pm.png?w=950" alt="" class="wp-image-1684" width="503" height="488" /></a></figure>
<h4 class="wp-block-heading">Explicit context, common service</h4>
<figure class="wp-block-image size-large is-resized"><a href="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-08-at-11.02.22-pm.png"><img src="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-08-at-11.02.22-pm.png?w=782" alt="" class="wp-image-1686" width="499" height="179" /></a></figure>
<figure class="wp-block-image size-large is-resized"><a href="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-08-at-11.02.43-pm.png"><img src="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-08-at-11.02.43-pm.png?w=942" alt="" class="wp-image-1687" width="516" height="498" /></a></figure>
<h4 class="wp-block-heading">Explicit context, unique service</h4>
<figure class="wp-block-image size-large is-resized"><a href="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-09-at-10.57.33-am.png"><img src="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-09-at-10.57.33-am.png?w=886" alt="" class="wp-image-1705" width="478" height="166" /></a></figure>
<figure class="wp-block-image size-large is-resized"><a href="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-08-at-11.03.35-pm.png"><img src="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-08-at-11.03.35-pm.png?w=1024" alt="" class="wp-image-1690" width="798" height="380" /></a></figure>
<h2 class="wp-block-heading">Conclusion</h2>
<p class="wp-block-paragraph">In conclusion, we saw how domain services provide APIs for Commands and Queries over domain resources and publish Events on specific state changes in a domain language</p>
<p class="wp-block-paragraph">There are 3 key takeaways from this post </p>
<ol class="wp-block-list"><li>Domain services function as a core business domain service</li><li>If the domain boundaries are not clear, then a large domain monolithic service can emerge coupling multiple teams </li><li>Fine-grained domain services can be monolithic if the provider system or the database model used by the domain service is shared across other services</li></ol>
<p class="wp-block-paragraph"></p>
Domain services implement core logic for a business domain and are a relied upon by experience and consumer services. Domain services can be self contained and store the business logic and state or rely on an external provider system (translating from a “raw system format” to a “canonical” domain format)
In this post we look at some of the types and design patterns for domain services especially around the monolithic-database services and the SOA-type domain services
Looking at these types and design patterns should help you and your team identify the type of domain service you are building, recognise some of the constraints in delivering business value and hopefully you can start to balance coupling and cohesion in your services better!
This is a longish post, so for those in a hurry – here are the key takeaways from this post
Domain services model core business domains vs other types of service oriented architecture which focus on layer, system or no-particular orientation
Domain services are about not leaking internal context out, so boundaries are important. If your service design teams knows about client contexts or clients know about your implementation details then the boundaries are not clear, leading to confused software
Going too broad with coarse domain services creates challenges with software that is used in multiple contexts leading to poor experience, data quality, change autonomy etc
Going too fine grained with domain services is a problem too, especially if multiple small services couple to each other and get chatty. This can create a hair-ball (cyclic graph)
Domain Services: Wide context
Domain services provide an implementation over the core business functions for a particular domain, for example Order, Shipping, Customer, Identity, Document etc.
Domain services provide an API for Commands (create/update) and Queries (Search, Get by ID) using a Domain Model. This model is key as it is the representation of the business model of the domain to external services. The domain model is determined through design processes such as Domain Events or Domain Storytelling using the Domain Driven Design (DDD) technique
Domain services also publish Domain Events which are emitted in a domain language and often notify subscribers of a change in the state of a domain object
A hypothetical C4 context model of a business with a Customer, Experience Channels, Experience Services, Domain Services and Systems
Commands, Queries, Events for State transfer
Domain services provide APIs for Commands and Queries and emit events called Domain events. These operations manage the state of a domain resource (HATEOS anyone?)
Commands on a resource enable the state transition, for example POST, PUT, PATCH. Queries enable the consumers to read the information about the current state, for example GET. Commands on a collection help us to search, add or remove items and Queries on a collection help search and list specific items by an identifier
Domain events are emitted on specific state changes. State transitions are done via operations in the API
Domain events are emitted on all or specific state changes, for example “OrderCreated”, “OrderSubmitted” or “OrderCancelled” and as you can imagine subscribers for these order domain events would be Shipment Domain service or Payment domain service
Types of Domain Services
Monolithic domain service
Provider backed domain service
Provider backed domain service with read-store
Self-contained domain service
Provider backed Domain Services
Provider backed domain service. The state is managed in the external system
Provider backed domain services with read-store
Provider backed domain services with read-store. State is in the external system, query can be in the domain service driven by events from external system
Self-contained domain service
There is no COTs system as the master, this domain service is the master with the business logic
Self-contained Domain services
Monolithic Domain Service
Monolithic database behind two or more domain services.
Service Design Patterns
There are 3 core patterns when building domain services
Monolithic Service: Single endpoint, large canonical data model, coupled contexts across different domains (SOA)
Explicit context, common services : Mono-repo with multiple teams from different domains and contexts in a single common service
Explicit context, unique service: Micro or Coarse-grained services with multiple contexts owned by the same team for a single domain service
Monolithic service
Explicit context, common service
Explicit context, unique service
Conclusion
In conclusion, we saw how domain services provide APIs for Commands and Queries over domain resources and publish Events on specific state changes in a domain language
There are 3 key takeaways from this post
Domain services function as a core business domain service
If the domain boundaries are not clear, then a large domain monolithic service can emerge coupling multiple teams
Fine-grained domain services can be monolithic if the provider system or the database model used by the domain service is shared across other services
Alok brings experience in engineering and architecting distributed software systems from over 20 years across industry and consulting. His posts focus on Systems Integration, API design, Microservices and Event driven systems, Modern Enterprise Architecture and other related topics
View all posts by alokmishra