46

Suppose that we are modelling a form using DDD; the form may have certain kind of business rules associated with it - perhaps you will need to specify an income if you are not a student, and you are required to list your children if you indicate that you are married. And if you specified a country, then it should have a valid country.

Does this kind of validation lives in the domain or application layer? Some other issues I was considering:

  • Certain frameworks, such as Laravel, provides validation rules that can validate input before a request hits the controller. Does it break DDD if validation is done at that level?

  • For cases like determining whether the country is valid, usually I will just query a database table of all the countries in the world. However, in DDD, this is likely (from my understanding) to be done on the domain layer. Is the domain layer allowed to access the DB, or must I use a non-SQL search to determine a valid country?

  • Is it necessary to validate the input both at the application, and domain layer?

2
  • 11
    You'r question assumes that there is always one, correct place to put everything. There isn't. Apr 6, 2016 at 5:53
  • 1
    What @RobertHarvey says. Validation should always be on the model, regardless of any validation by the "application" (isn't the model part of the application?). Any validation in the "application" should only be a repetition of the validation of the model - to enhance responsiveness of the UI, or should be related only to the "application" logic (as in: "on this form you can only enter ...", but I was assuming entity validation). Never trust the "application" layer for domain validation, it may not be your client sending the information... Apr 6, 2016 at 11:14

4 Answers 4

44

Does this kind of validation lives in the domain or application layer?

Application. The magic search term you want is anti corruption layer

Typically, the message received by your application will be some flavor of DTO. Your anti corruption layer will typically create value types that the domain will recognize. The actual command dispatched to the domain model will be expressed in terms of validated value types.

Example: a DepositMoney command would likely include an amount, and a currency type. The DTO representation would probably express the amount as an integer, and the currency code as a string. The anti corruption layer would convert the DTO into a Deposit value type, which would include a validated Amount (which must be non negative) and a validated CurrencyCode (which must be one of the supported codes in the domain).

Having successfully parsed the command into types the domain model understands, the command is executed in the domain, which may still reject the command on the grounds that it would violate the business invariant (the account doesn't exist yet, the account is blocked, this particular account isn't allowed to use that currency? etc).

In other words, the business validation is going to happen in the domain model, after the anti corruption layer validates the inputs.

The implementation of the validation rules will normally live either in the constructor of the value type, or within the factory method used to construct the value type. Basically, you restrict the construction of the objects so that they are guaranteed to be valid, isolating the logic in one place, and invoking it at the process boundaries.

8
  • Why application is the answer? According to your text the formal validation can be done both in the domain or in the application and the business validation in the domain only.
    – inf3rno
    Mar 4, 2017 at 17:21
  • @inf3rno because the questions specifically asked about validating a form, which is not related to the domain
    – timetofly
    Jun 27, 2018 at 2:18
  • 18
    This answer makes no sense. DDD's Anti-Corruption Layer is extra code you write in order to translate to/from an external (of another system) domain model and your DDD-based application's domain model. If there is no such external system, there is no Anti-Corruption layer. Also, validating business rules belongs in the Domain Model (and Domain layer), not the Application layer. As for DTOs, this is a technical component (in the Application layer) which may or may not exist in a DDD app. Converting between DTOs and Entities/ValueObjects has nothing to do with Anti-Corruption layers.
    – Rogério
    Aug 8, 2019 at 17:35
  • 1
    @Tebo The DDD "Anti-corruption layer" has nothing to do, per se, with DTOs, and it's not about data that gets passed from the UI and Application layers to the Domain layer. Maybe you should read the DDD book... (Also, "layers" are not "systems", they are layers in a single system, as described in the DDD book).
    – Rogério
    Apr 17, 2020 at 22:56
  • 1
    Anti-corruption is a term that just means that we should adapt external data shapes to value objects or entities in your domain to maintain. The UI is an external agent to the domain as much as a database or other adjacent domains are. Can you explain your perspective as to why you consider UI not to be external to the domain and what you think I am confused by? "I would suggest you try to actually read about it in the DDD book." - jeeeeez. I am proud to say I have read the book and that I'd never lord it over people like that. be nice
    – alaboudi
    Dec 6, 2020 at 4:27
9

Your problem domain model includes your domain business rules. Business rules are constraints on the elements of the model. They mean that an elevator doesn't move with the door open, that perishable goods aren't loaded into a non-refrigerated container, and that a cancelled order isn't shipped.

That doesn't mean that when your domain interacts with humans (via screens, forms etc) that there need be no validation or assistance. Just realize it is optional.

Consider that there are two types of business rules:- property rules that constrain the attributes of an object, and collaboration rules that constrain the addition and removal of collaborations between objects.

Business rules are different from logic rules, which are related to your programming language and check that values have been supplied and are not null etc.

Note: there is no concept in DDD of "modeling" your form.

1
  • This is probably the best answer here. Validating data PRIOR to hitting the domain layer is optional. The domain layer should catch any business level validation. If one does decide to put validation outside of the domain, then it is likely to simply validate the data formal coming from the API call or CLI. But similar to what @VoiceOfUnreason said, this would be a transportation layer that one can call an anticorruption layer (a.k.a ACL)
    – alaboudi
    Oct 7 at 19:16
0

Would specific state make model entity invalid? If yes, then the model must prevent the entity from getting to that state. That means the model must know how to validate itself.

But there is a slight problem : model validation often happens too late. Often, we want to do validation early, so user doesn't have to wait too long. That is why validation is often put into application logic.

As for context of validation : There is no problem of entity being able to query for additional data. But it shouldn't care where those data come from. It doesn't care if it comes from SQL, File or is just hard-coded. That is why repositories exist. The domain defines what kind of query it needs and lets someone else to take care of the implementation.

-2

The domain layer should contain all validation logic. Presentation, anti corruption layers or other dependant layers should reflect that.

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