Reputation: 654
I'm still studying such pattern (that is CQRS) and a colleague of mine started to implement it in our little project, but frankly I do really have some doubts about its implementation.
For starters we didn't use any particular framework and we developed in Java with Spring Boot (but this question is not programming language specific). Another thing you may find very weird about this is that the pattern has not been implemented completely, just the Command and Query Separation concept (no events, no aggregates, no real bus).
So let's take a look to what we have done, with a bottom-up approach:
I don't want to go much deeper in our implementation, since I just want to know if the following Command is feasible or not.
@Data // Lombok annotation
@Entity
class User {
@Id private Long id;
private String firstName;
private String lastName;
private Integer age;
}
@Value
class EditUserCommand {
private final User user;
}
@Service
class EditUserCommandHandler extends CommandHandler<EditUserCommand> {
@Inject
private UserRepository users;
@Override
public void handle(final EditUserCommand command) {
User old = this.users.findOne(command.getUser().getId());
User current = command.getUser();
current.setId(old.getId());
current = this.users.save(current);
}
}
And this is how we implemented the pattern (or rather the C&Q Separation concept) in our project... but frankly? I don't know if it's right and I found the code quite unconventional for a CQRS pattern. My questions then:
Thanks in advance for any reply.
Upvotes: 0
Views: 1624
Reputation: 646
You are right. The command should only contain the minimal information needed to perform the actual job (in the case of a ModifyUserAgeCommand, it could only contain the user id and the new age). In your handler, your repository should have the responsibility of re hydrating the model from the db and the you apply whatever changes applicable from the information contained in the command and persist with the repository. If you're using DDD, use the aggregate responsible for the user to apply the change and persist away.
By the way, as long as you treat reads (queries) and writes (commands) using separate classes and models, it's still CQRS. It's often a misunderstanding that CQRS has to include event sourcing, eventual consistency, DDD... IMHO, it just happens to work very well with these patterns.
Upvotes: 7