0

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)

1
  • 2
    ***** EDITED ***** <-- Please don't do this. Every post on Stack Exchange has a detailed edit history with a diff window. Announcing edits is completely unnecessary. We prefer that you incorporate your edits into your post, just as if you were writing a second draft of a paper. Oct 12, 2018 at 14:23

4 Answers 4

3

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?)

1
  • Thanks for the info, I have taken a look of what you said, could you please check my updates?
    – jpganz18
    Oct 12, 2018 at 11:09
1
+50

No, the DTO should normaly contain only structured data and basic validation regarding its internal structure, like non-nulls, string lengths, number ranges etc.

If you need to validate externally then you should use a Factory. One common pattern is to use an ACL that translates from remote models (i.e. Entities) to local models (i.e. Value objects). The ACL would not permit creation of an invalid DTO (not permitted by business rules).

Depending on your architecture/technology/programming language, the DTO is created asynchronous, by a different process in the background or synchronous, before it is used.

8
  • Thanks for the info, I read about the ACL but it seems to me shouldnt be async, could you please take a look?
    – jpganz18
    Oct 12, 2018 at 11:10
  • @jpganz18 it can be async, it depends on your architecture/technology/programming language, as I said. In fact, for better resilience it should be async. Oct 12, 2018 at 11:50
  • how can you make it async? I mean, I have to validate before continue with the saving process, I am using java
    – jpganz18
    Oct 12, 2018 at 11:56
  • @jpganz18 for example, a process is fetching remote data (from remote Bounded context) in the background, it converts them to local DTOs and then it persist them into the database. When they are needed they are loaded from the database. This does not work in every use-case, of course. Oct 12, 2018 at 12:10
  • Why would you use a Factory for validation? What would that look like? Oct 12, 2018 at 14:25
1

A few thoughts:

  • The question of whether or not it's OK to validate a DTO is largely irrelevant from a DDD perspective.

    You have to remember that the goal of DDD is to tackle complex domain problems. It is mostly agnostic to technical details of infrastructural layers/classes.

  • A Controller that calls a Service that calls a Facade that calls a Repository, in a transaction, all that to validate a DTO... That's a code smell right here if you ask me. Repositories are normally only called in specific situations where you rarely need to go through so many hoops.

    It seems to me that you're either sprinkling business rules haphazardly in your code base when they should really be in the Domain layer, or maybe DDD is not the right lens to look through at your problem.

8
  • Hi, no, the validation is made on the DTO (on the builder), then additional validations are made in other layers, the flow I mentioned is the one that happens when nothing is wrong, the endpoint saves information, thats why is a flow like that
    – jpganz18
    Oct 12, 2018 at 14:15
  • "I want to be sure is valid, but valid from the business point of view" : can you give a concrete example of such a validation? Oct 12, 2018 at 14:37
  • " 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." DTO should have input validation, and this is an input validation, but input validation should be like NonEmpty or NonNull or Size, no more complex logic
    – jpganz18
    Oct 12, 2018 at 14:44
  • If it's more complex and has to do with the domain, it should be in the domain layer. Otherwise, well, fine, validate all you need to validate, including through a service... I don't see what's blocking you, and it's not something DDD "theory" will be of any help with anyway. Oct 12, 2018 at 14:48
  • Also, I fail to see how "the" anti-corruption layer you're talking about fits into the picture. Oct 12, 2018 at 14:48
1

I think the issue here is that you are framing your data incorrectly. Your DTO cannot hold validation rules that require remote data to perform (what does DTO stand for again?). If any at all, a DTO should only have the very simplest of rules regarding the data it is holding. Your domain is responsible for business validation. Ideally, the process follows a flow similar to (from the POV of your application layer):

  1. Retrieve all data (domain objects) necessary to carryout requested command
  2. Coordinate data (tell the data to mutate itself)
  3. Persist mutated data

Importantly, the validation occurs during step 2 within the domain model. Your application simply invokes calls/organizes parameters to your domain. Your question seems to be mixing step 1 and step 2 together.

Is there a reason you cannot retrieve the data necessary to validate this extra field? There is no constraint on DDD imposing that every domain object must come from a single data source. Without your specific requirements it's difficult to offer a pointed solution, but I suggest you attempt to model your command handling like the above. That is, instead of using a service to validate some scalar field, use a service (or repository) to fetch a domain object (entity/aggregate/value) that encapsulates your data. This can then be passed around as part of the coordination in step 2 (think about vectors of change for this piece of data. Are there no rules?).

Does that make sense?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.