CQRS and synchronous operations (e.g. user registration)

I am in the process of adopting DDD concepts to develop our next projects, and more specifically, CQRS.

After reading a lot of things, I am now trying to implement a simple concept concept.

The fact is that I got stuck right after I started: p

I am trying to apply this approach to a simple user registration process, where are the steps:

  • The user fills out the registration form and sends a request
  • The application creates a user
  • The application authenticates the user (automatic login)
  • Application sends confirmation email to user
  • The application redirects the user to another place using a confirmation message

In terms of implementation, so far I get the following:

  • Controller action maps request data to RegisterCommand object
  • Controller actions require the command bus to process RegisterCommand
  • The "register" method of the command handler (UserService) creates a new user object (whether it be a new command or a factory object)
  • Model creates RegisterEvent register
  • The command handler asks the repository to save the new user object

To do this, the controller action does not know about it.

So, I suppose that everything in this context should be executed synchronously (except for sending by email), I can use the direct / synchronous command bus and in the controller action right after the command bus is called, I can request read-only "(query database), and if it exists, suppose everything went well, so I can give the user confirmation.

The automatic registration process is handled by an event handler.

Assuming this is correct, what if something goes wrong, how to tell the user the right information?

A common example is often used in articles that we can find over the Internet: a customer pays for his order using an expired credit card. The system accepts the request, informs the user that everything is in order, but after a few minutes the user receives an email with the message that his order cannot be processed.

Well, this scenario is acceptable in many cases, but for some others it is simply not possible. So where are the examples regarding these use cases ?: P

Thanks!

+7
source share
2 answers

The problem with far-fetched examples is that you can change your mind about how the β€œdomain” functions, so this example is not much discussed in particular. The basic premise that you seem to forget is that we must assume that everything will work. Everything else is associated with risk and mitigation. Taking this example, if I ask you, what if I lost 1 user registration in 100,000? What if I lose 1 out of 10? Why is this going to happen? Am I having big problems at this moment? Are future users most likely to register again when the system returns to the network and works as expected? When it will be? What if we controlled the quality of service and did not allow users to register, because we can not guarantee the quality with which they came to communicate with our brand? What should I do if the server explodes or the data center receives a nuk? Do we want to protect against this? You see, there is no right answer. Just different shades of gray. So how can we reduce the risk? We could make things synchronous, but this is only a guarantee at that limited time. What should I do if I had to restore a backup of 2 hours (for example, due to a damaged disk)? It lost 2 hours of registered users (maybe). This is happening ... I just wanted to point out the relativity of what I consider to be a false sense of security. Soften it, invest in what you cannot lose, make sure you have a good audit trail. This is probably not the answer you were looking for ...

+1
source

I think that this example of use for registration is closer to payment for the case of using the order than you think.

Most CQRS thought leaders offer a read-side check before issuing a command, giving your team a higher chance of success.

If the check is not performed on the read side, you know how to handle it - force the user to choose a different name before sending the registration command. If the test is successful, send a command - now you are probably talking a few hundred microseconds of AT MOST, where another user could log in and take the same username between the moment you confirmed this command and sent it. Very unlikely.

And in the very rare case when this happens, you act like the expired credit card example - the next time a user logs in, you provide them with an explanation and a form to send a new username - or send them an email mail: "Hey, someone has this username, click here to select a new one." Why does it work? Because you have a unique identifier for this user.

Take a look at a user registration page such as Twitter. As soon as you enter the username, he makes a small Ajax call and says "no, it's accepted" or "this one is good!" This preliminary check.

Hope this helps!

+3
source

All Articles