In a Domain Driven Development DDD, have a validation on a DTO that calls a external service is wrong, if yes, where should it be

domain-driven-designvalidation

I have this question, is more about pattern and in theory what is wrong or not instead of if is possible or not (because it is).

In a DDD design, I have a DTO that I am validating, to check not nulls, and other certain values.

There is a field that I just realised needs to be validated through a service that will make a network request.

I am using guice and this DTO is out of the context (Means I cannot inject services) but I think I should be able to.

According the theory, should the DTO have this kind of validations? this is and is not input validation at same point, this is because I want to be sure is valid, but valid from the business point of view (according me), but I also think it does not rely on the anti corruption layer.


The flow is like this:

  1. Controller is called, receiving as parameter DTOs with their own
    validations, they DTO are not in the guice context and Cannot inject
    a service or anything else
  2. Service is called (here I get info like logged user, service can
    inject) Service do some processing inside and then call a facade
    (facade can inject)
  3. Facade calls to the repositories , this method
    is transactional and then saves the info.

My validator is out of the context as well and cannot inject anything.

Any idea where would be the best?
This is a flow of an endpoint that saves info, thats the reason of the calls.

I saw validators on the repo, it calls an anti corruption layer, but to me is too late to validate this kind of info (im validating the info exists through an external api).

The validations in the DTO are made in the constructor.
Other layers have additional validations (such as not null, etc)

Best Answer

According the theory, should the DTO have this kind of validations?

Not normally, no.

What the DTO might include is a timestamp - what time was the information in the DTO known to be good?

The argument goes something like this: if you need to check with the remote service to know if something is valid, then the truth of that might change while the message is in flight - either while the validation response is returning to you from the remote service, or while your DTO is in transit to its destination.

The information is stale as soon as it is written down.

Instead, explicitly capture the information about when the data was known to be valid, and pass that along without making the remote service call.

Put another way - if you really need to ensure that your local data is in agreement with some remote data, then do that asynchronously to the real work.

(And also, be suspicious of your design - why are these two pieces of data that need to agree stored in different places?)