Business rule validators and command handler in CQRS - validation

I am new to CQRS and I am tying to make sense of business rule validation within the write side (domain). I know that client side validation should be done in terms of valid date (required field, string length, valid email, etc) and business rule/business domain related validation should be done in domain side. Actually, same client side validation rules should also be applied to command in the domain since we don't trust the users.
So, we have a valid command (AddEmailToCustomer) and the command handler is invoked on the command. Here is my approach to validation.
Create instances of two command validators in the command handler.
First one validates the command data same as client side validation (required field, valid email, etc.)
Second validator validates the data based on logic within the second validator. Something like "is this customer active", or what ever. I know the changing email doesn't fit here but it is not important. Important thing is there is a business validation here.
We look at the ValidationResult returned by the Validator.Validate(ICommand cmd) and we find out there are errors
We will not get a customer from repository to call on the UpdateEmail method on the AR. So what do we do at this point?
Do I throw and exception in the command handler and add these errors there?
Do I send the command to error queue or somewhere else?
Do I respond with something like Bus.Reply and return error code? If so, what do I do with the error messages?
How do I communicate these errors to the user? I know I can email them later but in a web scenario I can send a request id in the command (or use the message id), and poll for response with the request id and display the error messages to user.
Your guidance is appreciated.
Thanks

It's important to know that commands can be rejected after they are sent to the handler.
At the very least, you could encounter a concurrency violation that cannot be detected until the aggregate root is touched.
But also, the validation that can occur outside of the entity is simple validation. Not only string lengths, numeric ranges, regex matching, etc. but also validation that can be reasonably satisfied through a query or view, like uniqueness in a collection. It's important to remember that validation involving a materialized view is likely to be eventually consistent, which is another reason a command could be rejected from the aggregate, inside the command handler. That said, to preempt the situation, I often use read models to drive UI choices which only allow valid actions.
Validation that cannot occur outside an entity is your business logic validation. This validation is dependent upon the context in which it is run (see Udi Dahan's Clarified CQRS).
Business logic should not be in a separate validation service. It should be in your domain.
Also, I'm of the opinion that validation which occurs in the UI should be re-checked not in the command handler, but in the domain too. That validation is there to prevent corruption to the domain -- if it is not performed outside the domain then the domain is still subject to invalid parameters.
Using command handlers to duplicate this validation is only a convention. If no other front end is sending commands, then it is a useless duplicate. If there are multiple front ends, it is just one choice of where to place the then-necessary duplicate validation, and in those cases I prefer to handle it in the domain.
Lastly, you will need to bubble up commands rejected from within the handler. I accomplish this with exceptions as much as possible.

Related

Authorization of commands in Axon

Up until now I have been handling authorization in the CommandHandlers.
An example is I have an aggregate "Team" containing a list of managers (AggregateIdentifier from a User). All command handlers in the Team aggregate then verify the user executing the command is manager of the team.
The userId is injected as metadata in a CommandHandlerInterceptor based on the SecurityContext.
My main concern is, when I use sagas, it becomes an additional overhead to maintain the user context across the commands issued against different aggregates. Aside from that, the manager association can expire in the period the saga is running and subsequent failing commands, leading to an incomplete state which also needs to be handled with some rollback functionality.
Is it better to do the authorization in my controller layer to avoid the additional overhead or should I see it more as good practice to let my CommandHandlers decide whether the command is valid for the aggregate?
Authorization to perform certain operations/commands is something which I'd argue isn't domain specific logic. Instead, it is more a form of cross cutting concern which you need throughout your application. Thus, placing it in the #CommandHandler annotated method is not the ideal place in my head. However, placing it close by makes a lot of sense.
You have pointed out you are already using a CommandHandlerInterceptor to populate the Spring SecurityContext, thus I am assuming you are using a CommandDispatchInterceptor to populate the command's MetaData with information when you send a command out. This is a great use of the interceptor logic indeed, so I'd keep that in place. This however set's the information, it doesn't validate it.
To that end, you could build your own Handler Enhancer, which validates security metadata on a command. You could even build a dedicated annotation you'd add next to the #CommandHandler annotation, which describes the required roles. That way, the method still portrays what roles you need for the given command, but the actual validation can be done in this Handler Enhancer for you.
Now, let's circle back to your question:
Is it better to do the authorization in my controller layer to avoid the additional overhead or should I see it more as good practice to let my CommandHandlers decide whether the command is valid for the aggregate?
I think it's fine to do it in the aggregate, potentially making it cleaner through use of a Handler Enhancer. When it comes to your concern in the Saga, well, I think you should see that separate. The Saga handles events, facts that something has happened. Ignoring that fact because somebody whom initiated the operations which led to this fact doesn't have the rights doesn't resolve the point that it still has happened. Added, you are indeed not guaranteed on the timing of the Saga at all. Maybe your Saga deals with historical events, meaning it is completely out of scope.
If possible within your system, I would regard any command the Saga wants to publish as being sent by a "system user". The Saga is not something your users (which have specific roles) will directly influence; it is all indirect. The Saga is internal to your system, hence it is the system describing the intent to perform an operation.
That's my two cents to the situation, hope this helps you out #Vincent!

Validation within a asynchronous SAGA pattern - CQRS & DDD

Let's consider the flow below:
API client calls [POST] /api/v1/invitation/:InvitationId/confirm
Confirm the invitation within a SAGA
Eventually raise an InvitationConfirmed event to indicate success
We are some troubles finding a good place to validate the "event" we pass to the SAGA. For instance, we want to make sure that:
- The specified InvitationId exists
- The corresponding invitation is not expired or already processed
We tried a couple of things:
Fire a command:
Fire a command RequestInvitationConfirmation
Handle synchronously this command and return an error if the command is not valid OR otherwise raise the InvitationConfirmationRequested event.
The rest of the flow is the same
CONS:
- Requires us to follow a "request/response" pattern (synchronous within the HTTP request lifetime)
Raise an event:
Raise an event InvitationConfirmationRequested
Within the SAGA, query the Invitation service and perform the validations. If the command is not valid, we publish an event InvitationConfirmationFailed
(...)
CONS:
- As far as I understand SAGA should be used to orchestrate the flow. Here we are introducing the concept of "validation". I'm not sure it's the recommended approach.
Validation is a very common concept. How would you handle it in a distributed fully asynchronous system?
Important point in the design of this system is: "Who is the client of this API?".
If this client is an internal Service or Application that's one thing (as in a distributed app, microservices etc.).
If the API is used by third party client's, that's another thing.
Short answer
If the API is used internally between Services, sending a command with invalid Id in the system is a fault, so it should be logged and examined by the system developers. Also cases like these should be accounted for by having a manual way of fixing them (by some administrative backend). Log these kinds of stuff and notify developers.
If the API is used from third party apps, then it matters how responsibilities are separated between the API and the other part of the system that it uses. Make the API responsible for validation and don't send commands with invalid id's. Treat command with invalid ID's like fault, as in the first case. In this case if you use asynchronous flow, you will need a way to communicate with the third party app to notify it. You can use something like WebHooks.
For the second part of the validations check these series of blog posts and the original paper.
Long answer
If you search around you will see a lot of discussions on errors and validations, so here's my take on that.
Since we do separation of other parts of our systems, it's seems natural to separate the types of error that we have. You can check this paper on that topic.
Let's define some error types.
Domain Errors
Application Errors
Technical Errors (database connections lost etc.)
Because we have different types of errors, the validation should be performed from different parts of our systems.
Also the communication of these errors can be accomplished by different mechanisms depending on:
the requester of the operation and the receiver
the communication channel used
the communication type: synchronous or asynchronous
Now the validations that you have are:
Validate that an Invitation with the specified Id exists
Validate that the Invitation has not expired
Validate that the Invitation is not already processed (accepted, rejected etc.)
How this is handled will depend on how we separate the responsibilities in our application. Let's use the DesignByContract principle and define clear rules what each layer (Domain, Application etc.) should expect from the other ones.
Let's define a rule that a Command containing an InvitationId that doesn't correspond to an existing Invitation should not be created and dispatched.
NOTE the terminology used here can vary vastly depending of what type of architecture is used on the project (Layered Architecture, Hexagonal etc.)
This forces the CommandCreator to validate that an Invitation exists with the specified Id before dispatching the command.
In the case with the API, the RouteHandler (App controller etc.) that will accept the request will have to:
perform this validation himself
delegate to someone else to do the validation
Let's further define that this is part of our ApplicationLayer (or module, components etc. doesn't matter how it's called, so I'll use Layer) and make this an ApplicationError. From here we can do it in many different ways.
One way is to have a DispatchConfirmInvitationCommandApplicationService that will ask the DomainLayer if an Invitation with the requested Id exists and raise an error (throw exception for example) if it doesn't. This error will be handled by the RouteHandler and will be send back to the requester.
You can use both a sync and async communication. If it's async you will need to create a mechanism for that. You can refer to EnterpriseIntegrationPatterns for more information on this.
The main point here is: It's not part of the Domain
From here on, everyone else in our system should consider that the invitation with the specified Id in the ConfirmInvitationCommand exists. If it doesn't, it's treated like a fault in the system and should be checked by developers and/or administrators. There should be a manual way (an administrative backend) to cancel such invalid commands, so this must be taken into account when developing the system, bu treated like a fault in the system.
The other two validations are part of the Domain.
So let's say you have a
Invitation aggregate
InvitationConfirmationSaga
Let's make them these aggregates communicate with messages. Let's define these types of messages:
RequestConfirmInvitation
InvitationExpired
InvitationAlreadyProcessed
Here's the basic flow:
ConfirmInvitationCommand starts a InvitationConfirmationSaga
InvitationConfirmationSaga send RequestConfirmInvitation message to Invitation
And then:
If the Invitation is expired it sends InvitationExpired message to InvitationConfirmationSaga
If the Invitation is processed it sends InvitationAlreadyProcessed message to InvitationConfirmationSaga
If the Invitation is not expired it, it's accepted and it sends InvitationAccepted message to InvitationConfirmationSaga
Then:
InvitationConfirmationSaga will receive these messages and raise events accordingly.
This way you keep the domain logic in the Domain, in this case the Invitation Aggregate.
You have a command ConfirmInvitation containing InvitationId. You send it to your Invitation domain from InvaitationAppService. Your Invitation domain should look like this
...
public void ConfirmInvitation()
{
if (this.Status == InvitationStatus.Confirmed)
throw new InvalidInvitationException("Requested invitation has already been confirmed");
//check more business logic here
this.Status = InvitationStatus.Confirmed;
Publish(new InviationConfirmedEvent(...));
}
...
Your InvitationAppService should have something like below:
...
public void ConfirmInvitation(Guid invitationId)
{
// rehydrate your domain from eventstore
var invitation = repo.GetById<Invitation>(invitationId);
if (invitation == null)
throw new InvalidInvitationException("Invalid Invitation requested");
invitation.ConfirmInvitation(new ConfirmInvitation(...));
}
You don't need to introduce a new event InvitationConfirmationRequested. DDD is an approach in which your domain/business validation should reside inside domains. Don't try to fit other patterns or technologies in your domain. Validating your domain inside saga(which is used to orchestrate distribute transactions across the services) might create complexities and chaos

Command Validation in DDD with CQRS

I am learning DDD and making use of the CQRS pattern. I don't understand how to validate business rules in a command handler without reading from the data store.
For example, Chris wants to give Ashley a gift.
The command might be GiveGiftCommand.
At what point would I verify Chris actually owns the gift he wants to give? And how would I do that without reading from the database?
There are different views and opinions about validation in command handlers.
Command can be rejected, we can say No to the command if it is not valid.
Typically you would have a validation that occurs on the UI and that might be duplicated inside the command handler (some people tend to put it in the domain too). Command handler then can run simple validation that can occur outside of the entity like is data in correct format, are there expected values, etc.
Business logic, on the other hand, should not be in a command handler. It should be in your domain.
So I think that the underlying question is...
Should I query the read side from Command Handlers?
I would say no. Do not use the read model in the command handlers or domain logic. But you can always query your read model from the client to fetch the data you need in for your command and to validate the command. You would query the read side on the client to check would if Chris actually owns the gift he wants to give. Of course, the validation involving a read model is likely to be eventually consistent, which is of course another reason a command could be rejected from the aggregate, inside the command handler.
Some people disagree saying that if you require your commands to contain the data the handler needs to validate your command, than you can never change the validation logic within your handler/domain without affecting the client as well. This exposes too much of the domain knowledge to the client and go against the fact that the client only wants to express an intent. So they would tend to provide an GiftService interface (which are part of the ubiquitous language) to your command handler and then implement the interface as needed - which might include querying the read side.
I think that the client should always assume that the commands it issues will succeed. Calling the read side to validate the command shouldn't be needed. Getting two contradictory commands is very unlikely (users creating accounts with the same email address). Then you should have a mean to issue a corrective action, something like for example a Saga/Process Manager. So instead making a corrective action would be less problematic that if the command could have been validated and not dispatched in the first place.
It depends if the operation is async or not i.e does the user expect some immediate response. Gift ownership is basically a security feature and that can be done as a 'prep' operation before invoking the actual service or sending the GiveGiftCommand.
The only command validation you can do is to make sure it contains the data in the required format (UI validation) and that the user has the permissions to do that action. But after the command is sent it's up to the Domain to decide if other business constraints are respected.
If the user expects some immediate feedback, you can actually 'wait' until the command is completed and for that you can use an approach where a command handler can provide a result to the sender using a mediator . But this implies that at least some commands are executed in an immediate manner and that might not be the case in your app. However, this is the simplest approach if you want to just return a message error as opposed to implementing compensations and other stuff. Some use cases are simple.
About command handlers and business logic, I disagree with Tomasz Jaskuλa . A command handler is a function, a technical detail. You can put business logic in a command handler or a static function, it doesn't matter. Messages and their handlers are infrastructural components that can be used to implement functionality. For example, in an app you can have Domain Events, Application Events etc . They're all events i.e notification that something changed and you can have event handlers that reside in Domain or in other places.
There's no rule preventing you to 'read' from the db, however at least the read model theoretically is stale. However this might not be such a problem in 99% of cases. For the rest 1% you need very specific solutions.
I just asked the exact same question from a knowledgeable friend of mine and his answer was that it is OK to do this validation inside the command handler (in my case inside an akka persistent actor that interprets commands and writes events to the journal).
However if that is not possible for performance reasons (because processing validation inside a persistent actor would block the actor and that would be a scalability bottleneck for the whole app) then optimistic locking (OCC) can be used.
In other words the validation can be performed in an other actor (lets call it the validator actor - which is not in the persistent actor) , this will not block the persistent actor but it might happen that the data that is used for the validation has changed in the persistent actor while the validation was running in the validator actor) .
If the validator actor returns with an OK and all the data that has been used for the validation is still the same in the persistent actor (has the same version - version as in OCC) as it has been at the point when the command arrived to the command handler (persistent actor) then the command is accepted by the persistent actor , otherwise the validation needs to be resubmitted for re-evaluation to the validator actor.

Error Handler with Flux

I have a React.js application that I am refactoring to use the Flux architecture, and am struggling to figure out how error handling should work while sticking to the Flux pattern.
Currently when errors are encountered, a jQuery event 'AppError' is triggered and a generic Error Handling helper that subscribes to this event puts a Flash message on the user's screen, logs to the console, and reports it via an API call. What is nice is I can trigger an error for any reason from any part of the application and have it handled in a consistant way.
I can't seem to figure out how to apply a similar paradigm with the Flux architecture. Here are the two particular scenarios I'm struggling with.
1) An API call fails
All of my API calls are made from action creators and I use a promise to dispatch an error event (IE 'LOAD_TODOS_FAILED') on failure. The store sees this event and updates it's state accordingly, but I still dont have my generic error behavior from my the previous iteration (notifications, etc).
Possible resolution:
I could create an ErrorStore that binds to the 'LOAD_TODOS_FAILED' action, but that means every time I have a new type of error, I need to explicitly add that action to the ErrorStore, instead of having all errors be automatically handled.
2) Store receives an unexpected action
This is the one I'm really confused about. I want to handle cases when an action is dispatched to a Store that does not make sense given the Store's current state. I can handle the error within the Store to clean up the state, but still may want to trigger an error that something unexpected happen.
Possible resolutions:
Dispatch a new action from the store indicating the error.
I believe Stores are not suppose to dispatch actions (let me know if I'm wrong), and I still have the same issue as with an API error above.
Create a ControllerView for Error Handling that subscribes to every Store
I could define an errors property on every store, then have a View watching every Store and only act on the errors property. When the errors property is not null, it could dispatch new actions, etc. The disadvantages are that I need to remember to add every Store to this view whenever new ones are created, and every store has to have an error property that behaves the same way. It also does nothing to address API call failures.
Does anyone have a suggested approach for a generic Error Handler that fits into the Flux architecture?
TL;DR
I need to handle errors in most Action Creators and Stores. How do I setup consistent error handling that will occur for any type of generic error?
API call fails
If you want to avoid listing every error action in the ErrorStore, you could have a generic APP_ERROR action, and have properties of that action that describe it in more detail. Then your other stores would simply need to examine those properties to see if the action is relevant to them. There is no rule that the registered callback in the stores needs to be focused on the action's type, or only on the type -- it's just often the most convenient and consistent way of determining if an action is relevant.
Store receives an unexpected action
Don't issue a new action in response to an action. This results in a dispatch-within-a-dispatch error, and would lead to cascading updates. Instead, determine what action should be dispatched ahead of time. You can query the stores before issuing an action, if that helps.
Your second solution sounds good, but the dangerous thing you mentioned is "When the errors property is not null, it could dispatch new actions, etc" -- again, you don't want to issue actions in response to other actions. That is the path of pain that Flux seeks to avoid. Your new controller-view would simply get the values from the stores and respond by presenting the correct view.

Validating Individual Fields with AJAX - Where to put the logic?

I have a form that, when you enter text into a field and tab off, a jQuery event is triggered to validate that field by calling the relevant controller action. For example, I have an AccountController and a ValidateField action. When the user tabs off of the Username field, it will send a request to /Account/ValidateField. I will then return a JSON result back based on the validation.
Ok, so let's say I want to validate a Username field. I want to check that enough characters were used, that the username isn't already in use, and that the characters used are allowed. Two of these are easy. However, I need access to the database to check if the username already exists.
Where would I put this logic? In the Service layer?
In a world where absolutely no business logic replication takes place:
The minimum length of a name and checking validity of charaters sounds like domain logic, so that should be in the domain. Your ajax call would call the service layer which would in turn call the domain and validate.
Checking the username isn't already in use accesess the persistance layer, so I think this would be more likely to live in the service layer. The service layer could just query the repository for Users with the specified name, and if any are returned, it is invalid.
In a world where we actually care about performance:
The checking of username uniqueness probably does require a trip to the service layer to access the database. But as for the other two, this could be done in the UI to save a trip to the service layer, but would then need to be replicated in the domain. This is advocated by Udi Dahan:
Command Query Responsibility Segregation
He suggests UI validation, and then replicate it in the domain, but don't bother giving a helpful message from the domain because theoretically the only people who are likey to get that far will be hackers.

Resources