0

I have an aggregate root called User.
Here's an example of how it's modelised:

User: {
  id: string
  username: string,
  email: string,
  auth: LocalAuth {
    password: string
  }
}

In my application, I have an API route - POST /users/id/password - that allow users to change their password.
In order to change their password, we must ensure that users enters their old password. The request model should look like this:

{
  oldPassword: string
  newPassword: string
  newPasswordRepeating: string // in case of user errors
}

The controller that handle this request should do the following:

  • Check if the oldPassword is equal to the current one
  • Check if the newPassword is valid
  • Update the user data
  • Return the updated user data

In order to handle such business logic, I could create a VO model named PasswordUpdate (idk..). This VO could encapsulate the validation logic in its own model.

Does this kind of implementation faithfully follows the DDD rules?
Because in my case, this VO is never contained in an Aggregate Root and is not stored. The purpose is only to modelise a password update with a domain model.

Simon Bruneaud
  • 2,263
  • 2
  • 12
  • 24
  • 1
    Keep in mind, that identity/authentication/authorization are **almost never** a DDD / business layer concern. It's infrastructure and hence lies outside of your domain and highly depend on your infrastructure (i.e. authorization/identity framework used) and will change your your identity infrastructure changes. Your domain should be unaffected by it. And as such, don't treat "User" as a domain object. Just treat it as an entity/model of your infrastructure's framework. Just use the identifier (guid, id etc) to associate it with an entity inside your domain (i.e. "Person") – Tseng Apr 15 '18 at 12:48

1 Answers1

1

Does this kind of implementation faithfully follows the DDD rules?

Very short answer: go right ahead.

Short answer: the DDD police are not going to come after you anyway, so don't over think it.

Broad answer: I find that the description of Value Objects by Evans is something of a muddle, polluted by the fact that he was drawing from experience in Java.

But if you look really carefully, what's going on is that Evans is proposing the creation of a domain specific language that you can use to describe the behaviors of the model. Value objects are doing a few things: they are giving you domain specific types (so that the type system can assist, as it it able, in restricting the frequency of certain kinds of errors), they are giving you domain specific semantics (rather than insisting that all domain behaviors are described via operations on domain agnostic primitives), and they are providing an isolation layer between the domain behavior and the in memory representations of domain state.

The value of this is not restricted to the "domain model"; you should feel free to apply this abstraction everywhere it makes sense to do so.

BUT... there is a particular trap in the case that you describe that you should be aware of.

The domain model is something that you are supposed to able to change aggressively to meet the needs of the business, which of course can include changing the implementation of the value objects.

Messages, however, should be changed conservatively. Messages are part of the API. If we want to be able to release compatible clients and servers using a different cadence for each, then we need the interface between them to be stable. The message shouldn't be carrying domain rules with it (those belong in the model), it's just a representation of state.

"Validation" usually happens when we take the message (part of the api) and translate it into values understood by the model.

VoiceOfUnreason
  • 52,766
  • 5
  • 49
  • 91
  • Thx for this deep explanation :) Then the best way is to put **PasswordUpdate** outside of the domain layer but maybe create request models or something like that. – Simon Bruneaud Apr 12 '18 at 16:09
  • Not to mention that there's a part of the operation that should absolutely *not* be in the Domain IMO - the `newPassword == newPasswordRepeating` part. It's UI or applicative stuff. – guillaume31 Apr 12 '18 at 20:10
  • Is this a user wanting to change its password while logged in or a user resetting its password without being logged in? – Sebastian Oliveri Apr 13 '18 at 18:34
  • The DDD police are very real, and they will come after you. – Adam Vincent Apr 19 '18 at 17:08