Validation inside or outside entities?

A common question I get asked, especially around a vertical slice architecture, is where does validation happen? If you’re doing DDD, you might want to put validation inside your entities. But personally, I’ve found that validation as part of an entity’s responsibility is just not a great fit.

Typically, an entity validating itself will do so with validation/data annotations on itself. Suppose we have a Customer and its First/Last names are “required”:

public class Customer
{
    [Required]
    public string FirstName { get; set; }
    [Required]
    public string LastName { get; set; }
}

The issue with this approach is twofold:

  • You’re mutating state before validation, so your entity is allowed to be in an invalid state.
  • There is no context of what the user was trying to do

So while you can surface these validation errors (typically from an ORM) to the end user, it’s not easy to line up the original intent with the implementation details of state. Generally I avoid this approach.

But if you’re all up in DDD, you might want to introduce some methods to wrap around mutating state:

public class Customer
{
  public string FirstName { get; private set; }
  public string LastName { get; private set; }
    
  public void ChangeName(string firstName, string lastName) {
    if (firstName == null)
      throw new ArgumentNullException(nameof(firstName));
    if (lastName == null)
      throw new ArgumentNullException(nameof(lastName));
      
    FirstName = firstName;
    LastName = lastName;
  }
}

Slightly better, but only slightly, because the only way I can surface “validation errors” are through exceptions. So you don’t do exceptions, you use some sort of command result:

public class Customer
{
  public string FirstName { get; private set; }
  public string LastName { get; private set; }
    
  public CommandResult ChangeName(ChangeNameCommand command) {
    if (command.FirstName == null)
      return CommandResult.Fail("First name cannot be empty.");
    if (lastName == null)
      return CommandResult.Fail("Last name cannot be empty.");
      
    FirstName = command.FirstName;
    LastName = command.LastName;
    
    return CommandResult.Success;
  }
}

Again, this is annoying to surface to the end user because I have one validation error at a time being returned. I can batch them up, but how do I correlate back to the field name on the screen? I really can’t. Ultimately, entities are lousy at command validation. Validation frameworks, however, are great.

Command validation

Instead of relying on an entity/aggregate to perform command validation, I entrust it solely with invariants. Invariants are all about making sure I can transition from one state to the next wholly and completely, not partially. It’s not actually about validating a request, but performing a state transition.

With this in mind, my validation centers around commands and actions, not entities. I could do something like this instead:

public class ChangeNameCommand {
  [Required]
  public string FirstName { get; set; }
  [Required]
  public string LastName { get; set; }
}

public class Customer
{
  public string FirstName { get; private set; }
  public string LastName { get; private set; }
    
  public void ChangeName(ChangeNameCommand command) {
    FirstName = command.FirstName;
    LastName = command.LastName;
  }
}

My validation attributes are on the command itself, and only when the command is valid do I pass it to my entities for state transition. Inside my entity, I’m responsible for successfully accepting a ChangeNameCommand and performing the state transition, ensuring my invariants are satisfied. In many projects, I wind up using FluentValidation instead:

public class ChangeNameCommand {
  public string FirstName { get; set; }
  public string LastName { get; set; }
}

public class ChangeNameValidator : AbstractValidator<ChangeNameCommand> {
  public ChangeNameValidator() {
    RuleFor(m => m.FirstName).NotNull().Length(3, 50);
    RuleFor(m => m.LastName).NotNull().Length(3, 50);
  }
}

public class Customer
{
  public string FirstName { get; private set; }
  public string LastName { get; private set; }
    
  public void ChangeName(ChangeNameCommand command) {
    FirstName = command.FirstName;
    LastName = command.LastName;
  }
}

The key difference here is that I’m validating a command, not an entity. And since entities themselves are not validation libraries, it’s much, much cleaner to validate at the command level. Because the command is the form I’m presenting to the user, any validation errors are easily correlated to the UI since the command was used to build the form in the first place.

Validate commands, not entities, and perform the validation at the edges.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in DomainDrivenDesign. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • How do you consolidate common validation rules for a given property? For example, let’s say I have a bunch of commands that mutate FirstName and it is intrinsically limited to 50 characters. How do I ensure I’m not repeating that validation rule all over the place (making maintenance difficult if the common rule needs to change)?

    • jbogard

      I honestly don’t run into this very much. It’s rare for me to have more than a couple of forms that mutate the same value. If you’re using annotations, you can create a base class. If FluentValidation, create an interface then a validator for that interface.

    • jbogard

      That sounds like a good follow-up post though!

      • +1, would read. I really like the idea of creating interfaces for properties in the entity that have common database-imposed (or other intrinsic) validation rules and then layering command-based validation on top of that.

    • Slightly better, but only slightly, because the only way I can surface “validation errors” are through exceptions. So you don’t do exceptions, you use some sort of command result:

  • John Smith

    The command’s logic is outside of command class :P

    • jbogard

      The command here is a command message, not a command pattern object thingy.

  • PS

    Not worried about trusting the source of the commands at all? What happens if the layer responsible for passing the commands to the entities simply forgets to do the validation?
    Also, what is this? java style braces! :)

    • Nate

      I share the same concerns. How do you protect against other developers bypassing the validation? It seems to me someone could just as easily pass in an invalid ChangeNameCommand that hasn’t gone through validation and your entity ends up in an invalid state.

      • TomasJansson

        Really? It shouldn’t be that hard to encapsulate the domain to have only one else entry point which accept the commands. And before you call the method on the entities from that entry point you just validate the command. Straightforward if you ask me. That is, fan in at the entry of the domain, fan out in the domain to handlers after validation of the input.

        The funny part of this whole post is that it basically describe a functional approach but using a OO language.

        • PS

          It wouldn’t be hard, given it is usually the application service layer calling into (orchestrating) entities, this could easily be inplemented as a cross-cuttting concern (aspect). I am sure Jimmy isn’t calling into the fluent validation API manually before passing commands into entities either.

          The difficulty of implementation is not the point. The point is that in a typical onion architecture, a layer shouldn’t depend on any layer above it, only those below,
          the entities typically depending on no other layer. The approach suggested here makes the domain layer dependent on the caller (the layer above – application service layer) being responsible and only passing in validated commands. Also, always valid entities can no longer be guaranteed, given entities give up on validation completely.

          I can see the undeniable benefits of this, like binding the UI to the command directly and possibly auto-generating UI validation logic like asp. net mvc does, validation logic declared in only one place, and possibly others. I wouldn’t want to give up on always valid entities and independent layers to get them though.

        • Nate

          Wasn’t trying to imply it was difficult, I was more or less interested in what methods Jimmy and others would use to keep the domain in an always valid state. The example in the post doesn’t touch that aspect of it.

          While encapsulating the domain is certainly an easy option, it would probably be a last resort for me. I don’t want to add another layer on top of my domain unless there is good reason. After thinking about, another easy option would be only allow the creation of valid commands. Possibly a factory for commands that handles the creation and validation. Interested to here other options though as well. Being able to bind have validation logic that can be used for both UI and domain does seem appealing.

    • Stefano Sandes

      In my experience, ia resolve that with MediatR library and some lines of code to create a decorator for my commands. I scan my assembly that contain the commands and for each command, I search for an implementation of IValidationCommand, and in the interface implementation, I implement a FluentValidation AbstractValidator. The decorator try to validate the command. If command is valid, the handler is executed, otherwise no. The process to any other commands is automaticaly. Simply and efficient, in my opinion.

      https://uploads.disquscdn.com/images/60ae3506ee22c7b220d96780b0b53da0b30854f69e5bc9c4e2882067da8127c7.png

      https://uploads.disquscdn.com/images/52310155a5cfefb5704a70c694f0dabef5f905cdaba5bfd26b31ba2aa7fbbf78.png

      https://uploads.disquscdn.com/images/a55eb801693a61bb23170e1e029135e9f9db53312078b876779af63622c74c2e.png

  • Kurt Dowswell

    Hey Jimmy! This was a very timely post as I’ve been working on CQS validation myself. I wrote a post this morning after reading yours and would love some feedback if you have the time!
    https://medium.com/@kdowswell/cqs-validation-3a497655917c#.3ejjj6352

    • jbogard

      I like it! Are you using it in a real project?

      • Kurt Dowswell

        Cool! Yeah, I just finished a site for a client using this type of validation. It did things a little different but has the same concepts. I’m building a new site now with the exact implementation shown in the post. The company I work for is using this type of architecture in all our new sites. It has solved a lot of problems for us.

        Thanks so much for your posts and libraries. I use them a lot!

  • A.M

    Really, this approach is much better when you have service API model with DTOs , validating them before to map them in the entities.

  • Kurt Dowswell

    “Because the command is the form I’m presenting to the user, any validation errors are easily correlated to the UI since the command was used to build the form in the first place.”

    From this statement it sounds like, when using something like ASP.NET MVC, you are inheriting your command object in your ViewModel and posting your Command to the controller action correct?

    I’ve done this in a previous project and am now going away from this. Now I’m repeating my Annotation validation on the command and view model.

    Do you favor commands being exposed to the UI to simplify your process of validation and validator management or do you like the separation of responsibility of having the ViewModel on its own?

    • jbogard

      Nah my command isn’t the command pattern, it’s a command message. The command message IS the view model. The command handler is the work being done.

  • Adam

    I use a command validation approach but I’m just wondering what is the best way to support validations that require access to a database? Let’s assume that Name must be a unique. Where do you think that such logic should be placed? Inside a validation or in a command handler? Do you have any opinion about it?

    • jbogard

      I use fluent validation, so I can put that right in the validator class.

    • I often distinguish between validation and “verification,” the latter requires database or IPC access. In this case, I put the verification code into the handler which implements the command.

  • I think Validation is multi-level. I have validation running in:
    - Database, protecting against persisting invalid data, this is supported by EF validation attributes etc
    - Entity: Private setters, DDD use case methods, protecting against programming errors. Throwing exceptions.
    - Command model: protecting against invalid user input
    - Browser: protecting against invalid user input before it even hits the server

    Where I can I try to export the metadata of the command model to the browser, so that I don’t need to manually maintain the duplication.

    However I like the idea of accepting command models inside the Entities, which are already validated before passing through. This would cut out the need for duplicating validation in the Entities relying on exceptions.
    However that leaves the database and Browser.

    I do fear a certain loss of protection because you might not always change data directly based on the user’s input, but via entity logic or external services, but I suppose that’s where unit tests come in.

  • Erik Lott

    Create a “Name” value object containing “First” & “Last” properties, and have value object’s constructor enforce that first and last cannot be blank. Done.

    • jbogard

      Have you tried this? The web app user does not construct things. They just post a form.

  • rougou

    What if you have a business rule that requires validation against the entity’s state itself?
    For example, you have a shopping cart where you can only checkout 10 items. You will need to know the current # of items in the cart to perform this validation.
    Where would you put this type of validation logic?

    • jbogard

      In my validator? I use fluent validation that can grab dependencies as needed.

      • Viktor Nikolaev

        In this case you will load your domain model twice and your commands must know the business logic.
        Moreover it may lead to duplication if you validate commands against business rules.

        I think your way of validating commands is good only when validating user’s input and for simple rules

        • jbogard

          Yeah I agree, I do things a wee differently now