I think you need to separate two types of validation in this case; domain validation and application validation.
Application validation is what you have when you verify that the command property 'text' is between 20 and 200 characters; so you validate this with the GUI and with a view-model-validator that also executes at the server after a POST. The same goes for e-mail (btw, I hope you realize that an e-mail such as `32.d+"Hello World .42"@mindomän.local" is a valid according to the RFC).
Then you have another validation; check that article exists - you have to ask yourself the question why the article should not exist if there is indeed a command sent from the GUI that is about attaching a comment to it. Was your GUI eventually consistent and you have an aggregate root, the article, that can be physically deleted from the data store? In that case you just move the command to the error queue because the command handler fails to load the aggregate root.
In the above case, you would have infrastructure that handles poison messages - they would for example retry the message 1-5 times and then move it to a poision queue where you could manually inspect the collection of messages and re-dispatch those relevant. It's a good thing to monitor.
So now we've discussed:
What about commands that are out of sync with the domain? Perhaps you have a rule in your domain logic saying that after 5 comments to an article, only comments below 400 characters are allowed, but one guy was too late with the 5th comment and got to be the 6th - GUI didn't catch it because it was not consistent with the domain at the point of him sending his command - in this case you have a 'validation failure' as a part of your domain logic and you would return the corresponding failure event.
The event could be in the form of a message onto a message broker or your custom dispatcher. The web server, if the application is monolithic, could synchronously listen for both a success event and the failure event mentioned and display the appropriate view/partial.
Often you have custom event that means failure for many types of commands, and it is this event that you subscribe to from the web server's perspective.
In the system that we are working on, we're doing request-response with commands/events over a MassTransit+RabbitMQ message bus+broker and we have an event in this particular domain (modelling a workflow in part) that is named InvalidStateTransitionError
. Most commands that try to move along an edge in the state graph may cause this event to happen. In our case, we're modelling the GUI after an eventually consistent paradigm, and so we send the user to a 'command accepted' page and thereafter let the web server's views update passively through event subscriptions. It should be mentioned that we are also doing event-sourcing in the aggregate roots (and will be doing for sagas as well).
So you see, a lot of the validation you are talking about are actually application-type validations, not actual domain logic. There's no problem in having a simple domain model if your domain is simple but you are doing DDD. As you continue modelling your domain, however, you'll discover that the domain might not be as simple as it first turned out. In many cases the aggregate root/entity might just accept a method invocation caused by a command and change some of its state without even performing any validation - especially if you trust your commands like you'd do if you validate them in the web server that you control.
I can recommand watching the two presentations on DDD from Norwegian Developer Conference 2011 and also Greg's presentation at Öredev 2010.
Cheers,
Henke
You shouldn't delete the events from your event store. These represent something that happened.
If something happens now, then you should know it too, therefore add an event that will force your aggregate to go back to some previous state. That's a pity to delete information from your database.
think about the example of the cart from greg young and the removed items. May be tomorrow the information of compensating action might be of any value..
As for the saga, every thing is correct, as far as I know myself. You should think of the saga as of a state machine. It does only that.
It is a Command the saga is issuing to tell the aggregate to do something. Of this action there will be an event.
This event might be the corrective action you need, or might need to be denormalised in a view so that some user will see it to decide what to do.
It depends on your business rules. Either, there is an easy fix : the aggregate root knows that in such case , you do that, or the choice is too complex to be done programmatically ( development cost are too high) and therefore, you might propose this to some user, who might choose between different action.
Everything depend on the context of the compensating action. This is pure business rules. What should we do in this case or that case. This is something to ask your domain expert, and then choose with him, if it is better to develop an automatic solution or if the solution is to ask the user Ronald R., because he is the one to answer this question usually.
Best Answer
Yes. Part of the motivation for a "domain model" is to have all of the code responsible for ensuring the consistency of the data in "one" place. Evans describes solutions in the context of a three tiered architecture (application, domain model, persistence), and was discouraging the anti pattern of leaking the consistency checks into the application layer.
Consistency, here, means that we don't blindly change the data as described by the command, but instead make additional changes, if necessary, to ensure that the overall consistency is maintained.
In other words, domain models are typically associated with services, in the sense described by Udi Dahan. If we weren't interested in ensuring consistency of the commands, we would remove the domain model utterly and deal with the database directly.
So a signature like
typically isn't adequate, because in the general case we need to understand the current state to allow the domain model to calculate its own changes.
Let's consider a domain model of a game of tic-tac-toe. We can think of the game state as a representation of which parts of the grid are occupied by symbols, whose turn it is to play, whether the victory condition has been met.
If we get a "Play an X in the center position" command, what events do we emit? And the answer is "that depends"; we can't know what events to emit unless we already know "is it X's turn to play?", "is the center position available?" The answers to these questions depends on the state of the game, which is to say the events that have already happened. We need to know the current state of the game to map "Play an X in the center position" to the correct behavior.
Thus, we need a signature that is analogous to
with both the history of the aggregate and the command data being used to compute the new events.
See also: A Functional Foundation for CQRS/ES, by Mathias Verraes