What is the suggested approach for command validation in Akka?

Let’s say I have the following scenario. There is an UserActor. Apart from trivial properties like Id, FirstName, LastName, user internal state contains a CategoryId, which represents user adherence to specific Category. The category itself is a separate domain entity which has properties by its own. To perform the operation of assignment user to specific category I have to make sure that the specific category actually exists. What is the proper way of dealing with this kind of scenarios, which guarantee system consistency?

I am thinking about two solutions, but I am not sure which is worse than the other. :D

  1. Ignore rule “tell don’t ask”, and query CategoriesActor using Ask protocol to determine if category with specified Id exists or not?
  2. Spawn some sort of auxiliary actor (ValidatorActor) which perform all the necessary validations and reply with result to UserActor. In the meantime, UserActor will change its state to sth like “Waiting for Command Results” and will be stacking all incoming messages up until proper command validation results arrive.

The first solution denies everything I believe. The second does not scale too good in terms of class/actors proliferation. Moreover, if UserActor is persistent FSM I have no idea how to go back from this “waiting for command validation results” limbo. There is no Unbecome equivalent for FSMs :/.

I believe if you use Akka together with CQRS/ES approach you should deal with this kind of issues. How did you address them? I have read a few books about Akka and haven’t found any opinionated approach. It’s strange because in my opinion, it is such a fundamental use case.

I would really appreciate any hints.

NB: I am not a member of the Akka Team, so this is simply opinion from a longtime Akka Persistence / Sharding user. That said, I think “tell don’t ask” is an overblown motto, that has become far more of a religion than it should be.

Ask per se is mildly dangerous inside of an Actor, and there is a performance cost. But it’s often the right tool for the job, and the risks can be mitigated if you use it carefully, either piping the result back into the request loop with pipeTo or (if you do a lot of this, as I do) using the Requester library.

Mind, I’ll add one more note: the phrase “guarantee system consistency” is always a red flag in Akka. I’m assuming that you are taking the usual race conditions and such into account. In general, I try to structure my Actor systems to avoid the need for external consistency checks, since they are always subject to race conditions. But I do complex multi-Actor interactions using Requester all the time…

Here is my approach to the problem of complex command validation (requiring collaboration with other actors) using akka.actor.Stash: akka-ddd CollaborationSupport

Usage example: akka-ddd DummyAggregateRoot#generateEventuallyValid