Validation in DDD

I trying to implementing DDD for a CRM application, and I have some confused when I doing validation for domain model.

For example: I have an Customer entity, it’s aggregate root of Customer aggregate, when I create a new customer, I need to validate the data fill into the Customer entity by some rules like: checking the CRM Setting, is the customer phone number allows to duplicate, if don’t allows, I need to check the existing of phone number.

CRM Setting also being an aggregate too, in this case, validation for Customer aggregate need to using CRMSetting aggregate

The question here is: where and how I implementing the Validation?

You may consider two-step validation.

Use field-level validation on your command Data Transfer Objects (DTOs) and domain-level validation inside your entities. You can do this by throwing a (validation) exceptions in order to make it easier to deal with the validation errors.

I would create a validation (service) class to handle the specific user input validation.

The only solution that really works for me in a large enterprise application was Martin Fowler’s validation concept.

For this purpose I have written a small library in PHP to collect all validation errors: selective/validation. A middleware could transform the validation result into a proper HTTP 422 Error response object. On the client-side the error details (field and message) will be rendered into the specific form field.

thanks for your valuable answer, I realized that I should create a validation service (domain service) as you said and then using this service inside application service to validate, right?

Yes, I would call the validation service inside the application service (before you save the changes using the repository).

1 Like

I was have had the problem with this approach, inside validation service (domain layer) I need to call permission service to ensure the validity of some data fields, the problem here is I can not call the application service here because it is higher layer

I did something like this, use factory classes and construct DTO’s, i’m also using https://github.com/PHP-DI/Slim-Bridge and https://github.com/awurth/SlimValidation

 $data = json_decode($request->getBody());
 $validation = $this->validator->validate($data, UserUpdateRequestValidationRuleFactory::create());

    if (!$validation->isValid()) {
        $response->getBody()->write(json_encode(ValidationErrorResponseFactory::create($validation->getErrors())));
        return $response->withHeader('Content-Type', 'application/json')->withStatus(422);
    }

    $userUpdateRequestDTO = UserUpdateRequestDTOFactory::create($data->firstName, $data->lastName, $data->gender);