How to expose read-only calculations from business domain model on back-end to front-end using CQRS? A Read-Model vs. Write-Model Issue - domain-driven-design

I have two questions related to CQRS and Domain Driven Design (DDD).
As far as I understand the segregation idea behind CQRS, one would have two separate models, a read model and a write model. Only the write model would have access to and use the business domain model by means of commands. The read model, however, directly translates database content to DTOs by means of queries and has no access to the business domain at all.
For context: I am writing a web application back-end that provides calculation services for particle physics. Now my questions:
1.) My business domain logic contains some functions that calculate mathematical values as output from given measurement system configurations as input. So, technically, these are read-only queries that calculate the values on-the-fly and do not change any state in any model. Thus, they should be part of the read model. However, because the functions are heavily domain related, they have to be part of the domain model which again is part of the write model.
How should I make these calculation functions available for the front-end via my API when the read model, that should contain all the queries, does not have any access to the domain model?
Do I really have to trigger a command to save all the calculations to the database such that the read model can access the calculation results? These "throw-away" calculations will only be used short-term by the front-end and nobody will ever have to access the persistent calculation results later on.
It's the measurement configuration that has to be persistent, not the calculation results. Those will be re-calculated many times, whenever the user hits the "calculate" button on the front-end.
2.) I also feel like I duplicate quite a bit of data validation code, because both read model and write model have to deserialize and validate the same or very similar request parameters in the process chain http request body -> json -> unvalidated DTO -> validated value -> command/query.
How should I deal with that? Can I share validation code between read model and write model? This seems to dissolve the segregation.
Thanks in advance for all your help and ideas.

I think that what do you have is a set of domain services that with a given input they return an output.
As you said, this services are located in the domain. But, nothing denies you to use them in the read model. As long as you don't change the domain inside the functions, you can use them in any layer above the domain.
If, for any reason, this solution is not viable, because for example the services require domain objects that you cannot/don't want to build in the query side, you can always wrap the domain services inside application services. There you take in input a base object, you do all the transformations to the domain one, you call the domain service and you return the resulting value.
For the second question, you can build a validation service in the domain layer, as a set of services or simple functions. Again, nothing denies you to use them in the validation steps.
I've done the same in my last web app: the validation step of the form data calls a set of domain services, that are used also when I build the domain objects during the handling of a command. Changing the validation in the domain has as effect that also the Web related validation changes. You validate two times (before building the command and during the building of the domain object), but it's ok.
Take a look at the ports/adapters or the onion architecture: it helps a lot understanding what should stay inside a layer and what can be used by an overlapping layer.

Just to add my two pence worth.
We have microservices that use mongo as a backend. We use NET Core using mediatr (https://github.com/jbogard/MediatR) to implement a CQRS pattern in the MSs. We have .Query and .Command features.
Now in our world we never went to Event Sourcing. So, at the mongo level, our read and write models (entities) are the same. So what worked best for us was to have a single entity model which could be transformed into different models (if needed ) via each command/query handler(s).
If you are doing pure CQRS via event sourcing (so different read and write models) or something else then please ignore me! But this worked best for us.

Related

DDD Layers and External Api

Recently I've been trying to make my web application use separated layers.
If I understand the concept correctly I've managed to extract:
Domain layer
This is where my core domain entities, aggregate roots, value objects reside in. I'm forcing myself to have pure domain model, meaning i do not have any service definitions here. The only thing i define here is the repositories, which is actually hidden because axon framework implements that for me automatically.
Infrastructure layer
This is where the axon implements the repository definitions for my aggregates in the domain layer
Projection layer
This is where the event handlers are implemented to project the data for the read model using MongoDB to persist it. It does not know anything other than event model (plain data classes in kotlin)
Application layer
This is where the confusion starts.
Controller layer
This is where I'm implementing the GraphQL/REST controllers, this controller layer is using the command and query model, meaning it has knowledge about the Domain Layer commands as well as the Projection Layer query model.
As I've mentioned the confusion starts with the application layer, let me explain it a bit with simplified example.
Considering I want a domain model to implement Pokemon fighting logic. I need to use PokemonAPI that would provide me data of the Pokemon names stats etc, this would be an external API i would use to get some data.
Let's say that i would have domain implemented like this:
(Keep in mind that I've stretched this implementation so it forces some issues that i have in my own domain)
Pokemon {
id: ID
}
PokemonFight {
id: ID
pokemon_1: ID
pokemon_2: ID
handle(cmd: Create) {
publish(PokemonFightCreated)
}
handle(cmd: ProvidePokemonStats) {
//providing the stats for the pokemons
publish(PokemonStatsProvided)
}
handle(cmd: Start) {
//fights only when the both pokemon stats were provided
publish(PokemonsFought)
}
The flow of data between layers would be like this.
User -> [HTTP] -> Controller -> [CommandGateway] -> (Application | Domain) -> [EventGateway] -> (Application | Domain)
Let's assume that two of pokemons are created and the use case of pokemon fight is basically that when it gets created the stats are provided and then when the stats are provided the fight automatically starts.
This use case logic can be solved by using event processor or even saga.
However as you see in the PokemonFight aggregate, there is [ProvidePokemonStats] command, which basically provides their stats, however my domain do not know how to get such data, this data is provided with the PokemonAPI.
This confuses me a bit because the use case would need to be implemented on both layers, the application (so it provides the stats using the external api) and also in the domain? the domain use case would just use purely domain concepts. But shouldn't i have one place for the use cases?
If i think about it, the only purpose saga/event processor that lives in the application layer is to provide proper data to my domain, so it can continue with it's use cases. So when external API fails, i send command to the domain and then it can decide what to do.
For example i could just put every saga / event processor in the application, so when i decide to change some automation flow i exactly know what module i need to edit and where to find it.
The other confusion is where i have multiple domains, and i want to create use case that uses many of them and connects the data between them, it immediately rings in my brain that this should be application layer that would use domain APIs to control the use case, because I don't think that i should add dependency of different domain in the core one.
TL;DR
What layer should be responsible of implementing the automated process between aggregates (can be single but you know what i mean) if the process requires some external API data.
What layer should be responsible of implementing the automated process between aggregates that live in different domains / micro services.
Thank you in advance, and I'm also sorry if what I've wrote sounds confusing or it's too much of text, however any answers about layering the DDD applications and proper locations of the components i would highly appreciate.
I will try to put it clear. If you use CQRS:
In the Write Side (commands): The application services are the command handlers. A cmd handler accesses the domain (repositories, aggreagates, etc) in order to implement a use case.
If the use case needs to access data from another bounded context (microservice), it uses an infraestructure service (via dependency injection). You define the infraestructure service interface in the application service layer, and the implementation in the infra layer. The infra then access the remote microservice via http rest for example. Or integration through events.
In the Read Side (queries): The application service is the query method (I think you call it projection), which access the database directly. There's no domain here.
Hope it helps.
I do agree your wording might be a bit vague, but a couple of things do pop up in my mind which might steer you in the right direction.
Mind you, the wording makes it so that I am not 100% sure whether this is what you're looking for. If it isn't, please comment and correct my on the answer I'll provide, so I can update it accordingly.
Now, before your actual question, I'd firstly like to point out the following.
What I am guessing you're mixing is the notion of the Messages and your Domain Model belonging to the same layer. To me personally, the Messages (aka your Commands, Events and Queries) are your public API. They are the language your application speaks, so should be freely sharable with any component and/or service within your Bounded Context.
As such, any component in your 'application layer' contained in the same Bounded Context should be allowed to be aware of this public API. The one in charge of the API will be your Domain Model, that's true, but these concepts have to be shared to be able to communicate with one another.
That said, the component which will provide the states to your aggregate can be viewed from two directions I think.
It's a component that handles a specific 'Start Pokemon Match' Command. This component has the smarts to know to firstly retrieve the states prior to being able to dispatch a Create and ProvidePokemonStats command, thus ensuring it'll consistently create a working match with the stats in it by not dispatching any of both of the external stats-retrieval API fails.
Your angle in the question is to have an Event Handling Component that reacts on the creation of a Match. From here, I'd state a short-lived saga would be in place, as you'd need to deal with the fault scenario of not being able to retrieve the stats. A regular Event Handler is likely to lean to deal with this correctly.
Regardless of the two options you select, this service will deal with messages, a.k.a. your public API. As such it's within your application and not a component others will deal with directly, ever.
When it comes to your second question, I feel the some notion still holds. Two distinct applications/microservices only more so suggests your talking about two different Bounded Contexts. Certainly then a Saga would be in place to coordinate the operations between both contexts. Note that between Bounded Contexts, you want to share consciously when it comes to the public API, as you'd ideally not expose everything to the outside world.
Hope this helps you out and if not, like I said, please comment and provide me guidance how to answer your question properly.

DDD - Business decisions are based on database logic

I am trying to follow DDD in the following pattern.
Controller-----DataContract----> Domain Layer (DDD)
Controller-----Domain Object---> Repository---Entity--->EntityFramework
As you see in the above diagram, the domain layer is independent to make business decisions, but in my case, most of the business decisions are taken on the fly. For example,
if(Account Number Associated?)
Load CustomerDetails //A database call is needed
....
.....
if(Has customer another loan)
.....
.....
Load other loan details //A database call is needed
.....
.....
if(Was that repaid?)
....
....
Load collateral details //A database call is needed
.....
.....
Calculate collateral details and return.
else
Load other data //A database call is needed
else
Load other data //A database call is needed
else
Load other data //A database call is needed
As you see the above example, the application is making a lot of business decisions on the fly by making database calls. Since Domain Layer should not depend on the Repository Layer, I don't know how to proceed.
I may use Application service for database calls, but then Domain Layer wouldn't have any logic in it. All the logic would go into the Application Service.
Please help me in this.
-Pandian
There are at least three possible ways out
1) Design your repository to load the entire aggregate at once. This approach gives the domain model all of the state that it may need right away, rather than trying to load the state on demand.
2) Run the queries in the app service, and pass the data to the domain model. Ideally, you do this in advance (so that you are making a single call into the domain model), but when that doesn't make sense you have the domain model tell the app service what data is needed, and the app service finds that data and returns it.
3) Pass a repository into the domain model that allows it to read the data that it needs. This is essentially the "domain service" pattern, but used to access a data store.
In this design, the domain model is defining the repository interface, and the application provides the implementation. In other words, we're using the service provider pattern to keep the dependency arrows pointing the correct direction.
#Pandiarajan Domain layer can contain domain models(entities, value objects), domain services and domain events.
From your code above, you can create a domain service that encapsulates all these domain logic and concepts that are not naturally modeled as value objects or entities. These domain service can take a repository that handles all the database calls.
Note also that if the data you need to return are for read-only or reporting purpose, you may want to look for CQRS as alternative. In CQRS, all these read-queries can bypass your domain layer in presenting data. CQRS will eliminate the need of transforming your data to a domain model.

Are GetById, GetByX CRUD or Business logic methods or both of them

Colleague of mine told me - we don't have a Business logic, we only have CRUD like GetById, GetBySearchTerm, GetByParentID....so I started to wondering about these words.
After reading about DDD, those methods are CRUD, they have a mechanism to fetch data (also store, update, delete...) based on some specific code (usually SQL).
If Business analyst say me: "We need to show data about specific customer".
In my opinion this IS (GetById) a Business process, GetById should be placed inside Business logic part of the application and it contacts repository to fetch a data. Repository with CRUD methods is responsible to persist data based on some criteria.
I Know this question can lead to debate to have repository with atomic methods (GetById, GetBySearchTerm, GetByParentiId...) but my question is only simple - are those methods are CRUD or Business logic methods.
The short answer is that you should not be querying your domain model for any reason other than domain operations that are part of the write / transactional side of things. This side of things is more interested in commands issued at your domain in order to do / perform operations.
Anything related to displaying data should come from as simple a query / read model as is possible.
If you find that your queries require domain interaction you probably have a scenario where you may need to tell your domain to do something and, once completed, you can request the data through the query side.
Not every application is a DDD application. Some applications are just simple CRUD
The business logic would be the part of the application where you validate inputs (like get by id and id is a number between 1 and 99999). This then is passed on to the repository for the actual query.
But if your application is really a crud application then trying to apply DDD isn't going to help you.
Those methods can't be the business methods at all. As a CQRS practitioner i would suggest you to have different models for command and query side. May be you create a different bounded context that serves the whole reading (Query) process (You can create anemic /DTOs here) and another domain model that serves pure business logic purpose.
You can take a look at my blog for command and query separation.
https://aspxsushil.wordpress.com/2015/10/18/command-and-query-object-pattern/

Validating domain object properties in the Application layer. Is it okay?

In DDD, the Application layer is supposed to just perform coordination tasks, whereas the Domain layer is responsible of validating the business rules.
My question is about validating the domain object properties. For example, I need to validate that a required property has some value in it before persisting it to the database through repositories.
In terms of DDD, is it acceptable to perform this sort of property validation in the Application layer?
Kinds of validation
In the situation you describe, there are two different validation steps that you need to consider separately:
Input validation. This is the responsibility of an app service. The goal is to ensure that no garbage or harmful data enters the system.
Protecting model invariants. This is your domain logic. Whenever something in the domain changes, you need to make sure that the changes are valid within your domain, i.e. all invariants still hold.
Validating domain invariants as part of an app service
Note that sometimes you also want to validate domain invariants in an app service. This could be necessary if you need to communicate invariant violations back to the client. Doing this in the domain would make your domain logic client-specific, which is not what you want.
In this situation, you need to take care that the domain logic does not leak into the app service. One way to overcome this problem and at the same time make a business rule accessible to both the domain and the app service is the Specification Pattern.
Here is an answer of mine to another question that shows an example implementation for the specification pattern.
You can validate incoming data in your ui layer.
For example you can you symfony forms validation or just check for necessary data inside your layer with Rest.
What about Domain Layer, it depends.
You didn't precise what kind of domain object it is.
Mostly you do such kind of validation by creating Value Object, with creation logic inside. For example Email Value Object, you can't create wrong one, otherwise it will throw exception.
Aggregates can perform validation before executing method and it's called invariants. For example, user has method becomeVIP, inside a method there is constraint, that only user with name 'Andrew', can become a VIP.
So you don't do validation after the action, but before the action. You don't let your aggregate go into wrong state.
If you have logic, which is not correlated with aggregate you put it in domain service, for example email uniqueness check.
Rather than "validating hat a required property has some value in it" at the periphery of the Domain, I prefer to make sure that it can never become null in the Domain the first place.
You can do that by forcing consumers of the constructors, factories and methods of that entity to always pass a value for the property.
That being said, you can also enforce it at the Application level and in the Presentation layer (most web application frameworks provide convenient ways of checking it these days). Better 2 or 3 verifications than one. But the domain should be the primary source of consistency.

DDD - which layer DTO should be implemented

I am learning about DDD so apologies if my question is naive. I think I need to use Local Data Transfer Object in order to display data to the users as a lot of properties are not part of any of Entity / Value Objects.
However, I am not sure where this DTO should be implemented - in a Domain Layer or in an Application Service Layer. The DTO implementation seems part of the Domain, but it means that when I create a collection of DTOs in the Service Layer and pass it to a Presentation Layer, I have to reference Domain Layer in Presentation Layer, which seems wrong.
What is the correct way to implement DTO using DDD principles?
Define the DTO to the layer where the source of the values comes from.
Relative to OP's question: place the DTO in the Application Service Layer. DTO is an output of that layer, it makes sense if you define it there. Don't put your DTO in the Domain Layer. The Domain Layer does not care about mapping things to serve external layers (the domain does not know there is a world outside of its own).
Presentation Layer (closes to consumers)
This could be your API
Has Models or Dto definitions of its own with attributes relative to its layer. If this is an API then Models/DTO have attributes for formatting or data type validations
This is the "Application Root" (meaning that it must reference both Domain Service layer, Data/Infrastructure Layer to be able to inject services)
Maps data between ApplicationService.Dto and Presentation.Dto
Application Service Layer
Has Dto definitions of its own to be able to return data without exposing the domain entities.
Bridge between Presentation Layer and Domain Layer.
Contains Application Services. See answer https://stackoverflow.com/a/3840552/1027250 for detailed definition of Application Services.
Domain Layer
Domain entities
May contain Interfaces bridging the infrastructure layer, defined in words that can be understood by the business, free from technical terms (IE: IExcelReport, IGoogleSheetReport, IRepository)
May contain "Domain Services"
Data / Infrastructure Layer (closest to your database or external services)
Database infrastructure (mapping).
Excel libraries if you define this layer as infrastructure code.
Mail or notification services.
PDF output files
Such DTOs that are exposed to the outside world become part of a contract. Depending on their form, a good place for them is either the Application Layer or the Presentation Layer.
If the DTOs are only for presentation purposes, then the Presentation Layer is a good choice.
If they are part of an API, be it for input or output, that is an Application Layer concern. The Application Layer is what connects your domain model to the outside world.
As an interesting observation, it follows that the Presentation Layer should access the domain model only through the Application Layer. Otherwise, we lose our single point of access - we'd have multiple layers invoking the domain model. The Application Layer exposes all of our use cases. Whether they are invoked by a call from another service or by the Presentation Layer makes little difference.
Sources
The core of these concepts I learned from The Red Book by Vaughn Vernon. (I would quote from it, but I don't have it handy.) The chapters about the Application Layer and the Presentation Layer are relevant.
Primarily, my conclusions come from being strict with the concepts as presented by Eric Evans and Vaughn Vernon, and prioritizing freedom in the domain model, as this is Domain-Driven Design:
The domain model should be easy to change. That means not exposing domain objects externally, as having external dependants would make them hard to change (without breaking things).
The Application Layer is the external point of access. It is what defines the use cases on the domain model. That means not operating on the domain model from elsewhere. The Presentation Layer can only go through the Application Layer. Nobody likes having to deal with many different points of access!
Yorro is right about where to place DTO but I encourage you to avoid "DTO mindset". This way of thinking collides with DDD way of thinking.
Thinking about "I need a DTO here" is thinking about technical representation (as plalx says); it is a level of abstraction too low. Try a higer level of abtraction and think about your domain, user's tasks and your UI.
Do you need get view data to the user? Bring it to UI through a View Service that return a specific YourViewInfo class.
Do you need to send data to some Service to perform a task? Send it a specific TaskMessageInfo class or a specific Command class.
When you begin to modeling the internals of these classes is when you should start to thinking about its technical representation; then you could reach to the conclusion that could be, i.e., DTO classes for convenience.
Thinking this way helps you to model the system and doesn't trigger questions like
Where to put or belongs this thing?
DTO and Domain are different layers.
So it requires mapping from one to another and usually it is done in what is called Application Services layer.
Take a look at the following articles to go deeper with DTO and layering:
Is Layering Worth the Mapping? by Mark Seemann
DTO vs Value Object vs POCO: definitions
Hexagonal (Ports/Adapters) Architecture
What has to be mentioned here is so-called Hexagonal (Ports/Adapters) Architecture [Vernon, the red book p. 125]. It is very convenient to place objects that represent data for the external (outside the domain & the application) comsumers. The architecture is the great addition to Layered Architecture generally implied by DDD.
Here is the example.
Along with ports/adapters for a DBs, email services etc.
We may define a ports/adapters/http/ui/myestore/ShoppingCartResponse.valueobject.ext (assume we use some imaginary programming language EXT) that contains the data your UI application MyEStore will use to show the end user his shopping cart state.
ShoppingCartResponse.valueobject.ext is created by ports/adapters/http/ui/myestore/EStoreHTTP.adapter.ext (for brevity it could be a synonim for a very slim HTTP REST API controller from REST world in our example).
The adapter asks the domain service ShoppingCart.service.ext for aggregates, entities, other value objects. Then it creates the desired ShoppingCartResponse.valueobject.ext from them (by itself or with creators - factories, builders etc.). Then sends the value object as an HTTP response to the consumer.
DTO or Value Object?
Whether ShoppingCartResponse would be a value object or a DTO (.dto.ext) you should decide based on
The particular structure of your Ports/Adapters object hierarchy;
If it is justified to have another type of object, a DTO, in the system, or it is better to keep only value objects only;
A semantic meaning of DTO vs value objects in object hierarchy;
The responsibilities differentiation between them: say your value object would do some invariants logic-keeping, whereas DTO could be just a dumb object with no logic.
I would prefer starting with the simplest approach, allowing only for value objects, and add DTOs only as the clear architectural need in them appears.
This approach gives much flexibilty yet it keeps code design clean and simple. Ports/Adapters section accommodates objects that belong together (the adapter, VO or DTO, their creators) and keeps Application Layer clean keeping the space for more relevant application layer objects.

Resources