I have a Meeting Object:
Meeting{id, name, time, CreatedBy, UpdatedBy}
and a
MeetingAssignee{id, MeetingID, EmployeeId, CreatedBy, UpdatedBy)
Meeting, as Aggregate root, has a method AssignEmployee.
I was about to pass in the current user to the Meeting object as I call AssignEmployee, so that it can update its audit fields accordingly.
But this doesn't seem right - is it? Obviously I can keep the audit fields public and change them later - perhaps at service level?
What is everyone's else preferred method for updating these fields?
Please note: We are not using Nhibernate, but a custom ORM which does not have anything automatic in place.
Thanks.
Auditing and logging are fun as they are usually needed everywhere in the application and they are both requirements (logging is a requirement from the OPs guys).
Without knowing much of your model, and since auditing must be a requirement, I would pass the current user to AssignEmployee and instead of having a line there that says AuditBlahBlahBlah, I would add an event (maybe MeetingUpdated or AssigneeAdded... you'll find a good name) and that event gets dispatched to the class that does the auditing. In this way the Meeting class has no clue about auditing and dispatches business events for auditing purposes (which, in my view, is very DDDish).
I wonder what other people might say (hopefully, I can learn something new!)
Consider using domain events.
Everything interesting in your domain model should raise an event shouting aloud of what just have happened. From outside, just attach log handler that dumps them in db or somewhere else.
That way - you don`t need to mess up your domain with some kind of IAuditService's.
Even better - domain model can use eventing as a way to communicate inside of itself.
To show why that`s a good idea - visualize that we are describing domain model of morning, sunrise and flowers.
Is it responsibility of sun to tell all the flowers that they should open? Not really. Sun just needs to shine brightly enough (to raise an event), light must travel down to earth (there must be some kind of infrastructure that makes eventing possible) and flowers must react themselves when receiving light (other domain models should handle events).
Another analogy - it's responsibility of driver to see what's the color of traffic lights.
You could possibly make the call to the audit service from the service layer when persisting or updating the entities, with the audit service having being injected into any services that require audit functionality, and persist the newly created entities as quickly as possible.
I see how it could be hard to work out how-and-when to audit, especially if your entities are going to exist as usable entities in the system sometime before being persisted. Even if they exist for some time before being persisted, maybe you could create in-memory audit data, containing the details of their creation and then persist that when the entities are eventually persisted. Or have the created-by, created-on, modified-by, modified-on, etc. data set as private fields in the entity and write it out to an audit log when the entity is persisted?
I'd be interested in what the trade-offs would be.
I think that the auditing properties are not a concern of your domain model. If all the use cases available in your application services layer use the domain model to make changes in the system, and the aggregate roots publish anything that has happened as Domain Events later on you can implement a handler for any event and it saves them in the audit log format you need.
Related
DDD can only be use in event triggered? like POST,PUT,DELETE? I try to search on the internet for how many months, I can only see that they use DDD logic when the user form is submitted. But when retrieving the data (GET) there is no logic involve, they just query it and display in the U.I. Is that acceptable if I store computed total in the database or retrieve the data and compute it?
. Please enlighten me. Thank you.
If your application is designed with DDD for a specific bounded context, then it SHOULD be the only authoritative application for that context. It means it SHOULD be the only one able to update the that context's state. It means every changes to that context SHOULD go through this application domain layer.
If every change to this context is done by your application, and if you enforce all domain rules when updating your context state, then your context state CANNOT be persisted in an invalid state. In that situation, you don't need to enforce domain rules when reading the context's state, as this was already done when updating it.
In conclusion :
You MAY bypass your domain logic validation when reading/querying your application state IF you prevent other components from violating your authority over that context.
I wonder if you can help. I am writing an order system and currently have implemented an order microservice which takes care of placing an order. I am using DDD with event sourcing and CQRS.
The order service itself takes in commands that produce events, the actual order service listens to its own event to create a read model (The idea here is to use CQRS, so commands for writes and queries for reads)
After implementing the above, I ran into a problem and its probably just that I am not fully understanding the correct way of doing this.
An order actually has dependents, meaning an order needs a customer and a product/s. So i will have 2 additional microservices for customer and products.
To keep things simple, i would like to concentrate on the customer (although I have exactly the same issue with products but my thinking is that if I fix the customer issue then the other one is automatically fixed also).
So back to the problem at hand. To create an order the order needs a customer (and products), I currently have the customerId on the client, so sending down a command to the order service, I can pass in the customerId.
I would like to save the name and address of the customer with the order. How do I get the name and address of the customerId from the Customer Service in the Order Service ?
I suppose to summarize, when data from one service needs data from another service, how am I able to get this data.
Would it be the case of the order service creating an event for receiving a customer record ? This is going to introduce a lot of complexity (more events) in the system
The microservices are NOT coupled so the order service can't just call into the read model of the customer.
Anybody able to help me on this ?
If you are using DDD, first of all, please read about bounded context. Forget microservices, they are just implementation strategy.
Now back to your problem. Publish these events from Customer aggregate(in your case Customer microservice): CustomerRegistered, CustomerInfoUpdated, CustomerAccountRemoved, CustomerAddressChanged etc. Then subscribe your Order service(again in your case application service inside Order microservice) to listen all above events. Okay, not all, just what order needs.
Now, you may have a question, what if majority or some of my customers don't make orders? My order service will be full of unnecessary data. Is this a good approach?
Well, answer might vary. I would say, space in hard disk is cheaper than memory or a database query is faster than a network call in performance perspective. If your database host(or your server) is limited then you should not go with microservices. Moreover, I would make some business ideas with these unused customer data e.g. list all customers who never ordered anything, I will send them some offers to grow my business. Just kidding. Don't feel bothered with unused data in microservices.
My suggestion would be to gather the required data on the front-end and pass it along. The relevant customer details that you want to denormalize into the order would be a value object. The same goes for the product data (e.g. id, description) related to the order line.
It isn't impossible to have the systems interact to retrieve data but that does couple them on a lower level that seems necessary.
When data from one service needs data from another service, how am I able to get this data?
You copy it.
So somewhere in your design there needs to be a message that carries the data from where it is to where it needs to be.
That could mean that the order service is subscribing to events that are published by the customer service, and storing a copy of the information that it needs. Or it could be that the order service queries some API that has direct access to the data stored by the customer service.
Queries for the additional data that you need could be synchronous or asynchronous - maybe the work can be deferred until you have all of the data you need.
Another possibility is that you redesign your system so that the business capability you need is with the data, either moving the capability or moving the data. Why does ordering need customer data? Can the customer service do the work instead? Should ordering own the data?
There's a certain amount of complexity that is inherent in your decision to distribute the work across multiple services. The decision to distribute your system involves weighing various trade offs.
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.
Despite having studied Domain Driven Design for a long time now there are still some basics that I simply figure out.
It seems that every time I try to design a rich domain layer, I still need a lot of Domain Services or a thick Application Layer, and I end up with a bunch of near-anemic domain entities with no real logic in them, apart from "GetTotalAmount" and the like. The key issue is that entities aren't aware of external stuff, and it's bad practice to inject anything into entities.
Let me give some examples:
1. A user signs up for a service. The user is persisted in the database, a file is generated and saved (needed for the user account), and a confirmation email is sent.
The example with the confirmation email has been discussed heavily in other threads, but with no real conclusion. Some suggest putting the logic in an application service that gets an EmailService and FileService injected from the infrastructure layer. But then I would have business logic outside of the domain, right? Others suggest creating a domain service that gets the infrastructure services injected - but in that case I would need to have the interfaces of the infrastructure services inside the domain layer (IEmailService and IFileService) which doesn't look too good either (because the domain layer cannot reference the infrastructure layer). And others suggest implementing Udi Dahan's Domain Events and then having the EmailService and FileService subscribe to those events. But that seems like a very loose implementation - and what happens if the services fail? Please let me know what you think is the right solution here.
2. A song is purchased from a digital music store. The shopping cart is emptied. The purchase is persisted. The payment service is called. An email confirmation is sent.
Ok, this might be related to the first example. The question here is, who is responsible for orchestrating this transaction? Of course I could put everything in the MVC controller with injected services. But if I want real DDD all business logic should be in the domain. But which entity should have the "Purchase" method? Song.Purchase()? Order.Purchase()? OrderProcessor.Purchase() (domain service)? ShoppingCartService.Purchase() (application service?)
This is a case where I think it's very hard to use real business logic inside the domain entities. If it's not good practice to inject anything into the entities, how can they ever do other stuff than checking its own (and its aggregate's) state?
I hope these examples are clear enough to show the issues I'm dealing with.
Dimitry's answer points out some good things to look for. Often/easily you find yourself in your scenario, with a data shoveling from db up to GUI through different layers.
I have been inspired by Jimmy Nilsson's simple advice "Value objects, Value objects and more Value objects". Often people tend to focus to much on Nouns and model them as entity. Naturally you often having trouble in finding DDD behavior. Verbs are easier to associate with behavior. A good thing is to make these Verbs appear in your domain as Value objects.
Some guidance I use for my self when trying to develop the domain (must say that it takes time to construct a rich domain, often several refactoring iterations...) :
Minimize properties (get/set)
Use value objects as much as you can
Expose as little you can. Make you domain aggregates methods intuitive.
Don't forget that your Domain can be rich by doing Validation. It's only your domain that knows how to conduct a purchase, and what's required.
Your domain should also be responsible for validation when your entities make a transition from one state two another state (work flow validations).
I'll give you some examples:
Here is a article I wrote on my blog regarding your issue about anemic Domain http://magnusbackeus.wordpress.com/2011/05/31/preventing-anemic-domain-model-where-is-my-model-behaviour/
I can also really recommend Jimmy Bogard's blog article about entity validations and using Validator pattern together with extension methods. It gives you the freedom to validate infrastructural things without making your domain dirty:
http://lostechies.com/jimmybogard/2007/10/24/entity-validation-with-visitors-and-extension-methods/
I use Udi's Domain Events with great success. You can also make them asynchronous if you believe your service can fail. You also wrap it in a transaction (using NServiceBus framework).
In your first example (just brainstorming now to get our minds thinking more of value objects).
Your MusicService.AddSubscriber(User newUser) application service get a call from a presenter/controller/WCF with a new User.
The service already got IUserRepository and IMusicServiceRepository injected into ctor.
The music service "Spotify" is loaded through IMusicServiceRepository
entity musicService.SignUp(MusicServiceSubscriber newSubsriber) method takes a Value object MusicServiceSubscriber.
This Value object must take User and other mandatory objects in ctor
(value objects are immutable). Here you can also place logic/behavior like handle subscriptionId's etc.
What SignUp method also does, it fires a Domain Event NewSubscriberAddedToMusicService.
It get caught by EventHandler HandleNewSubscriberAddedToMusicServiceEvent which got IFileService and IEmailService injected into it's ctor. This handler's implementation is located in Application Service layer BUT the event is controlled by Domain and MusicService.SignUp. This means the Domain is in control. Eventhandler creates file and sends email.
You can persist the user through eventhandler OR make the MusicService.AddSubscriber(...) method to this. Both will do this through IUserRepository but It's a matter of taste and perhaps how it will reflect the actual domain.
Finally... I hope you grasp something of the above... anyhow. Most important is to start adding "Verbs" methods to entitys and making the collaborate. You can also have object in your domain that are not persisted, they are only there for mediate between several domain entities and can host algorithms etc.
A user signs up for a service. The user is persisted in the
database, a file is generated and saved (needed for the user account),
and a confirmation email is sent.
You can apply Dependency Inversion Principle here. Define a domain interface like this:
void ICanSendConfirmationEmail(EmailAddress address, ...)
or
void ICanNotifyUserOfSuccessfulRegistration(EmailAddress address, ...)
Interface can be used by other domain classes. Implement this interface in infrastructure layer, using real SMTP classes. Inject this implementation on application startup. This way you stated business intent in domain code and your domain logic does not have direct reference to SMTP infrastructure. The key here is the name of the interface, it should be based on Ubiquitous Language.
A song is purchased from a digital music store. The shopping cart
is emptied. The purchase is persisted. The payment service is called.
An email confirmation is sent. Ok, this might be related to the first example. The question here is, who is responsible for orchestrating this transaction?
Use OOP best practices to assign responsibilities (GRASP and SOLID). Unit testing and refactoring will give you a design feedback. Orchestration itself can be part of thin Application Layer. From DDD Layered Architecture:
Application Layer: Defines the jobs the software is supposed to do and directs the
expressive domain objects to work out problems. The tasks this layer
is responsible for are meaningful to the business or necessary for
interaction with the application layers of other systems.
This layer is kept thin. It does not contain business rules or
knowledge, but only coordinates tasks and delegates work to
collaborations of domain objects in the next layer down. It does not
have state reflecting the business situation, but it can have state
that reflects the progress of a task for the user or the program.
Big part of you requests are related to object oriented design and responsibility assignment, you can think of GRASP Patterns and This, you can benefit from object oriented design books, recommend the following
Applying UML and Patterns
We are trying out CQRS. We have a validation situation where a CustomerService (domain service) needs to know whether or not a Customer exists. Customers are unique by their email address. Our Customer repository (a generic repository) only has Get(id) and Add(customer). How should the CustomerService find out if the Customer exists?
Take a look at this blog post: Set based validation in the CQRS Architecture.
It addresses this very issue. It's a complex issue to deal with in CQRS. What Bjarte is suggesting is to query the reporting database for existing Customer e-mail addresses and issue a Compensating Command (such as CustomerEmailAddressIsNotUniqueCompensatingCommand) back to the Domain Model if an e-mail address was found. You can then fire off appropriate events, which may include an UndoCustomerCreationEvent.
Read through the comments on the above blog post for alternative ideas.
Adam D. suggests in a comment that validation is a domain concern. As a result, you can store ReservedEmailAddresses in a service that facilitates customer creation and is hydrated by events in your event store.
I'm not sure there's an easy solution to this problem that feels completely clean. Let me know what you come up with!
Good luck!
This issues does not have to be that complex:
Check your reporting store for customer uniqueness before submitting the UpdateCustomer command.
Add a constraint to your DB for uniqueness on email address. When executing the command, handle the exception and send a notification to the user using a reply channel. (hences never firing CustomerUpdated events to the reporting store.
Use the database for what it's good for and don't get hung up on ORM limitations.
This post by Udi Dahan http://www.udidahan.com/2009/12/09/clarified-cqrs/ contains the following paragraph:
"Also, we shouldn’t need to access the query store to process commands – any state that is needed should be managed by the autonomous component – that’s part of the meaning of autonomy."
I belive Udi suggested simply adding a unique constraint to the database.
But if you don't feel like doing that, based on the statement above, I would suggest just adding the "ByEmail" method to the repository and be done with it - but then again Udi would probably have a better suggestion..
Hope I am not too late...but we faced a similar situation in our project, we actually intercept the command executor and attach it with the set of rules created for that command, which in turn uses a query to fetch the data.
So in this case, We can have a class by the name, CustomerEmailMustBeUniqueRule which is fetched by the RuleEngine when the command "RegisterCustomerCommand" is about to be executed by RegisterCustomerCommandExecutor. This rule class has the responsibility to query the database to find if the email id exist and stop the execution by raising the invalid flag...