1

Say I have a domain entity User:

class User {
  constructor (username, email, password) {
    this.username = username
    this.email = email
    this.password = password
  }
}

Now, all users need a way to validate their username and email

There are two ways I can think of doing so:

  1. Inside the domain entity (domain/entities/User.js)
class User {
  constructor (username, email, password) {
    this.username = username
    this.email = email
    this.password = password
  }
  
  validate () {
    // validation logic
    // ...

    if (!this.username.isValid || !this.email.isValid) {
      return false
    } else {
      return true
    }
  }
}
  1. In a domain service (/domain/services/validateUser.js)
function validateUser (userToValidate) {
  // validation logic
  // ..
  
  if (userIsValid) {
    return true
  } else {
    return false 
  }
}

Either way, the use case/application service calls the validation logic

function createUserUseCase (username, email, password) {
  const user = new User(username, email, password)
  const isValid = user.validate()

  // ...
  // or... calling a service

  const user = new User(username, email, password)
  const isValid = validateUser(user)

}

So, should entities also carry logic or only hold data? Can I put validation logic inside an Entity, or do I have to create a service that receives a user and validates the user?

Thanks.

3
  • 1
    Do your validations cause side effects, e.g. hit a database, file system? Or are they merely processing in-memory data (i.e. executing validations on their member variables)?
    – Andy
    Jun 22, 2020 at 6:01
  • @Andy In this case, in-memory. Sorry to ask; would the domain not talk to external sources anyway? Or are there situations in which domain can call a database, etc.?
    – kibe
    Jun 22, 2020 at 6:07
  • 1
    Domain is usually made database-agnostic, but even then in the domain you tend to define service interfaces which you expect to inject as dependencies and which can therefore use pretty much any dependency on their own. It's important to distinguish between these services and e.g. aggregates.
    – Andy
    Jun 22, 2020 at 6:51

1 Answer 1

2

Answering your question (about services)

A domain service is by definition always outside of a domain entity:

SERVICE: An operation offered as an interface that stands alone in the model, with no encapsulated state.
- Eric Evans

A service is meant for operations that do not belong to the entity, for example because it's not a responsibility of the entity and should therefore be decoupled from it, or because it's about several entities.

So by definition you cannot have a service "INSIDE" an entity. "Inside" the entitiy, it's called an operation. This formally answers your question.

Answering the question behind your question (where to validate)

Unfortunately this doesn't tell you where to put the validation: should it be an operation of the entity? Or shall it be in a service? There are many factors to consider, and there are numerous questions on SE (for example this recent one or this older one) on where to put a validator.

Both are possible, but it really depends on how you see the world in your design. The following questions shall help you to make your own mind with solid arguments:

  • is the validation a responsibility of the entity ?
  • is there any behavioral difference between a validated entity and a non-validated entity? (i.e. not the behaviors of the context that uses the User, but really of User itself) ?
  • may the validation change for other reasons than a change in the entity? And in particular, could the validation in principle involve other entities / or even repositories (e.g.verifying that no other user exists with the same email, or that the domain of the email is not on a blacklist).
  • could there be reasons that justify that validation shall be performed before the User is even created, i.e. the validation is clearly not a responsibility of User?
  • is it possible that there are different kind of validation with different purposes? E.g. a part being the responsibility of the entity, a part being of the responsibility of a service?

Now you can assess yourself, if it's a good idea or not to have the validation INSIDE as operation, or OUTSIDE as service.

6
  • It's a good answer, but you make it sounds like there should be a a single place to validate. In reality, different concerns are validated in different places. The domain should be responsible for validating business rules. If you want to store a name in a database field with 20 chars, validating that the length doesn't exceed 20 is not a business rule.
    – Rik D
    Jun 22, 2020 at 9:00
  • @RikD Indeed! Excellent point: there may be several kinds of validations. To my defense, I said both are possible but I never said that they were mutually exclusive. In addition the accepted answer to the first example of validator questions addresses this very well and I assume OP will read it. Thanks for the suggestion, I’ve added a question to make sure that it’s not forgotten.
    – Christophe
    Jun 22, 2020 at 9:12
  • 1
    @RikD what do you mean a length of a certain field is not a business rule? Surely the business may dictate that a username may not be longer than 20 characters. If it does, where would such rule fit in your case?
    – Andy
    Jun 22, 2020 at 9:37
  • @Andy Indeed, this is an uncomfortable question, because in some cases the 20 is a rule decided by business (exactly as in old forms where there was a box for every letter). But in some case it’s an arbitrary implementation decision made for example for the DB schema that propagates to UI and other levels (and in some case it doesn’t even account for character encoding). The interesting point in RikD’s comment, is that anyway, there can be different types of validations (i.e. each with different answers to the proposed set of questions) which all could fit at different places in domain model
    – Christophe
    Jun 22, 2020 at 9:52
  • @Andy thanks for all the answers, seriously. I'm just learning DDD and it fascinates me how it makes you leave the database for last and focus on how your app behaves independently of external sources. do you guys have a good resource where I can learn more about DDD? is the Eric Evan's book still relevant? thanks
    – kibe
    Jun 22, 2020 at 21:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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