4

I've been struggling to figure out a clean way to validate things when objects have complex relationships and the validation requires expensive operations (e.g., making DB queries or other RPCs).

Looking around, I couldn't quite find something that answers this question, so here goes. I've read a bit about domain driven design, domain models, service layers, data mappers, transaction scripts, and anemic vs rich domain models; there's a lot and it's overwhelming with the various opinions.

As an example, let's say we have an Document object, and it has a list of usernames, but you're only allowed to have usernames for active users. You check if a user is active by calling to an external UserService. This example can easily grow as you add e.g., attachments, sharing settings, etc, that can only be used with a document under certain conditions and also have their own internal invariants/validation, or require more calls to the database or other external services.

But, just where does/should that validation take place?

  1. At the level where user input is collected? Leaving the chance for other input points or more internal code to ignore this rule (or more likely, copy/paste slightly different version of it around)?
  2. On the Document object itself? Which results in a strange binding between the Document object and the heavy-weight dependency (e.g., as a constructor arg, or a required arg to some isValid function)
  3. Way down in a persistence layer, so it's always enforced, but muddling persistence with business logic?
  4. In some middle layer? Still leaving the chance for more internal code to go directly to the persistence layer and skip the rule?

As complexity grows, -- let's say saving a Document now has a feature where it'll automatically create an Attachment (which can be created independently and also have their own internal invariants/validation) -- how do you structure/design/architect the application to avoid the sort of problems/short-comings as mentioned above as things grow and change?

1
  • What happens when users are were linked to documents and then deactivated?
    – plalx
    Feb 5, 2017 at 4:19

1 Answer 1

3

Validation can be put in many places depending on the type of validations. Common places are the UI for fast responses/great ux, on the command itself, on the command handler and on the Aggregate. In the specific case of the Document with usernames and the external service I whould put the validations on the command handler. After that validation passes then the Document Aggregate would enforce the consistency on other business rules that refer to the root entity and its sub-entities.

1
  • I strongly agree with this. Each layer has its own validation: domain validation its about logic & business: it should be the most complex one. You could add some validation at entity level: ie email has to have specific format (think of entity invariants)
    – user237329
    Sep 22, 2017 at 11:05

Your Answer

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

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