Some questions about the command bus

Posted on by Matthias Noback

So far we've had three posts in this series about commands, events and their corresponding buses and handlers:

Now I'd like to take the time to answer some of the very interesting questions that by readers.


The difference between commands and events

Robert asked:

[...], could you possibly explain what are the main differences between a command bus and an even dispatcher?

Marc and Florian answered the question already, but I'd like to repeat the answer here. The main difference is: events tell you that something has happened, while a command tells you that something needs to happen. From this it follows that nobody might be interested in an event, but somebody should be interested in a command, because it has to be handled somehow.


Disadvantages of using a command bus

mTorres asked

[...] is it great that you state the advantages but can you also post the disadvantages?

Some suggestions are offered, which also recur in other people's comments:

1) Increases complexity with another layer of abstraction [...]

2) You must glue each command with its handler somewhere and load that information on every request [...] like the DI graph

To respond to the first reason: in my experience the level of complexity drops when you start using commands and the command bus. As mentioned it helps you disentangle the technical details of the input from the domain-specific actions that will be executed in the core of your application. Indeed, this adds a lot of flexibility as well.

The second reason is not a problem either; the number of services in your DI container doesn't affect performance at all. What matters is the number of objects that you actually instantiate. This number is still very low, because the SimpleBus packages provide lazy-loading of command and event handlers out-of-the-box.

One disadvantage that I can come up with myself is that it may require a bit more thinking from the developer (this is not meant to be cynical by the way!). Using commands and events (and also separating command from query responsibilities) generally leads to better design because you think harder about the characteristics of your domain. Still, this takes a bit more effort, which you might not want to put in if the application is not supposed to live a long life (i.e. needs no or just a little bit of maintenance).

One other disadvantage may be that you will have more classes. To me this is more like an advantage, since if the application still does the same thing, this means that those extra classes are highly focused on performing one task well.

One, maybe bigger disadvantage, might be that it's not as simple anymore to offer CRUD-style actions. Commands are task-oriented instead of data-oriented. Still, you should keep in mind that just like you don't need go "DDD-all-the-way", you don't need to use commands everywhere in your application.


The command as constructor argument

Daniel S asked:

[...] why does the Command Handler not receive the actual command in the constructor?

class SignUpHandler implements CommandHandler
{
    public function __construct(SignUpCommand $command) { /* ... */ }
}

Florian answered this one quite nicely:

I really think it should be passed as an argument of the handle() method. Otherwise, one handler instance = one command. You wouldn't be able to process 2 different command instances with the same handler instance.

That's right. A handler itself is an immutable service, which probably needs other immutable services to do its job. Hence, the constructor should be reserved for injecting dependencies. Then the same handler can be used to handle multiple instances of the same type of command.


How to return a value from the command bus

Gabriel Birke asked:

How would the controller know that the signup was successful or not and display the correct message?

That's a very good question. And again, Florian provided some great answers already. Several kinds of problems may occur if we handle a command in the same process:

  • The user may have provided invalid input data
  • The provided input data may result in an invalid state
  • An unexpected runtime error may occur (e.g. network failure)

We can already catch validation errors before we hand the command over to the command bus. In fact, we should verify that the command itself contains valid data and provide human-oriented error messages to the user if it doesn't. The other two kind of problems will result in regular failures, just like they would in a non-command oriented application. They can be handled in any way you like (e.g. allowing the user to retry the action, or show an error page).

Any other execution path should be considered the happy path: everything goes well. So if the command bus finally returns control to the controller that asked it to handle a command, you can assume that no problems occurred and, for instance, redirect to a "thank you" page.

Something that Florian already mentioned as well: when using commands you follow the Command-query separation (CQS) principle: a function is either a query (i.e. it returns something) or a command (i.e. it affects state). Both are mutually exclusive. So a command is not supposed to return anything and a query is not supposed to modify anything.


Could commands handle themselves?

mTorres asked another question which is highly relevant:

[...] maybe we could create Commands that executes themselves (with the __invoke method)? It will be less flexible but you'll have also less complexity to handle, what do you think?

It is an intriguing idea. However, you have to keep in mind that the set of commands that might be able to handle themselves is very small. State machines and situations where command objects are created ad hoc might allow for self-handling commands. See also an example of self-executing commands from Ross Tuck's library Tactician, which has more or less the same goals as SimpleBus.

The notion of self-executing commands recently resulted in an interesting debate when Taylor Otwell demoed the use of self-executing commands in the new version of Laravel. As a follow-up, Ross wrote something which I consider a highly convincing recommendation against the use of these types of commands.

The takeaway of this is that:

  • Commands - as discussed in this series - should be simple messages only.
  • Related behavior should always be separated from the message itself.

Of course, SimpleBus (as well as Tactician) allows you to implement commands in any way, so you could easily replicate Laravel's self-handling commands. In fact, let me just show you a rough outline:

use SimpleBus\Command\Command;
use SimpleBus\Command\Bus\CommandBus;
use SimpleBus\Command\Bus\RemembersNext;
use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\Bus\SelfHandling;

interface HandlesItself extends Command
{
}

class SupportsSelfHandlingCommands implements CommandBus
{
    use RemembersNext;

    private $container;

    public function __construct(Container $container)
    {
        $this->container = $container;
    }

    public function handle(Command $command)
    {
        if ($command instanceof HandlesItself) {
            $arguments = $this->resolveArguments(;
            $this->container->call([$command, 'handle']);

            /*
             * We consider the command handled,
             * so we don't call the next command bus
             */
        } else {
            $this->next();
        }
    }
}

You only need to make sure that this particular command bus is called before any regular command handler might be called.

Conclusion

Thanks everyone for asking these questions. As you can see, there are quite a lot of details and reasoning behind the answers.

The next post will be about collecting events.

If you're interested to learn more about these subjects and start using commands and events in your (Symfony) application, check out my Hexagonal Architecture training website.
PHP hexagonal architecture command bus events event bus SimpleBus
Comments
This website uses MailComments: you can send your comments to this post by email. Read more about MailComments, including suggestions for writing your comments (in HTML or Markdown).
Tomek Chmielewski

Good article, thanks!
I have a question regarding querying the repository. How can I handle pagination (offset, limit) with the stiff repository interface? Should I apply it as a query method parameters?

richardhagen

Hi! I'm looking at this problem now, and am thinking to use self-handling commands instead of seperate classes (maybe we can have the command and handler in the same php file?)Anyway, is the $this->container->call($class, 'handle'); from symfony or laravel? (if laravel, does symfony have any similar features, I can't find any information regarding that...)

Ben Glassman

@matthiasnoback:disqus I have a question about how to access data in the controller action that is only known by the handler after successful handling. Consider the case of a CreateBlogPostCommand($title, $text) that would create a blog post. The controller should redirect to the detail url after creation but needs to know the $id of the created blog post. What is your opinion of having the CreateBlogPostCommand having a way for the CreateBlogPostCommandHandler to set the $id of the created blog post on the command instance itself. The controller could then create the command, validate it (if necessary), if valid pass to the command bus for handling and then call CreateBlogPostCommand::getId() to retrieve the created id for building a redirect URL. The downside of this is that its an indirect approach and introduces mutability to the command. Alternatives would be to dispatch a CreateBlogPostCommandSuccess event from the handler and listen to that in the controller? What are your thoughts?

Tomasz Hanc

Hi, I'm still learning how to proper implement commands and command handlers and I've got some questions.

How would you split logic for editing employee into commands. Employee entity has methods:

changeName($firstName, $lastName)

changeEmail(Email $email)

changePhonenumber(Phonenumber $phonenumber)

changeAddress(Address $address)

I created 4 commands and 4 command handlers. It works nice when from UI a client can change only one thing at time. But how handle the case when a client has whole form (crud-like) for all data for employee. Should I create a new command ChangeEmployee or something. And in fact change all these things in ChangeEmployeeHandler or maybe better is to delegate everything to other command handlers. What I mean here is that ChangeEmpoyeeHander would create 4 commands and would ask command bus to the rest. Which solution is better?

Mike Mx

Commands should reflect UI tasks. If your UI does change all that user's fields in one action then go for one command.

Christian Flothmann

Hi Matthias,

the line

$arguments = $this->resolveArguments(;

looks somehow misplaced in the last code example. :)

Stefan

Hi Mattias,
I just read through your CQS series and first of all I want to thank you for these excellent posts.
I put my comment under the "Some questions about the command bus" article because I think it fits here best.

Because there are some questions left for me, I was just wondering about some issues, how to solve them especially in a Symfony application.
1) Should a role be checked in the controller or in the command handler or both?
2) Where do I set flash messages? In the controller or for example as an event which will be recorded in a command?

Christian Flothmann

> 1) Should a role be checked in the controller or in the command handler or both?

To me, access checks would be performed as soon as possible. So, either don't let the user access the controller at all or check access there. Doing this in the command handler can become a tricky part if you don't want to always pass the user who triggered a certain command at all (for example, when commands are handled in a separate process that doesn't know anything about the signed in user).

Mikhail Ogarkov

For me it is totaly unclear how to display object after it is created by command handler and how this situation meant to be solved by CQS. If i have non unique input and create some object how then i could know what i have created. Can i return some sort of ID from command handler and redirect then to method that use query part of CQS to read that object? Is this a valid form of CQS?
BTW thank you for series of interesting articles.

Matthias Noback

The command bus has no return value. So instead of waiting for the ID to come back from the database, the ID should be one of the values of the command object. If you then hand it over to the command bus, and nothing fails, you can safely assume that an entity with the given ID has been created (usually an ID is a UUID, instead of an auto-incremented ID from the database).

Miles Johnson

In regards to the last point, I agree with placing the handle functionality in the command. The command as it is currently stands is simply a POPO that holds data. If the handle method is moved the command, its role shifts to an object that processes data that it is given.

I cannot think of a situation (albeit my knowledge of the command bus is limited) where a command and handler will not have a 1 to 1 relationship. If anything, I could see developers creating a single command that holds data, and re-using that command for each unique handler. Combining the 2 would remove this scenario.

Correct me if I'm wrong, just curious!

Conall O'Reilly

It sounds like the object you're describing would be the same as a handler currently is, but have a handle(array $data) method? or handle($arg1, $arg2) method? Even if you prefer to do so, there's a lot to be gained from using Commands as Value Objects (or POPOs with data as you call them). Immutability and Readability would be the big ones for me.

But I think the bigger point is the one that Matthias nailed in the post, it doesn't matter so much that commands have a 1 to 1 relationship with one eachother, what's more important is they both have very different responsibilities, one is the what (and the input validation that goes with it) and the other is the how (and the dependencies it needs to carry out its internal logic):

Matthias Noback

In reply to Miles, I would write something like Conall did :) Thanks for some good questions and answers!

mTorres

I've just wanted to thank you for taking the time and bother to answer the questions that came along the series, very well reasoned answers Matthias, thank you!

Matthias Noback

Thanks for letting me know!

devosc
"it helps you disentangle the technical details of the input"

For me, the possibilities start to change once named arguments are supported by the Bus. Once this functionality is required, the patterns can change to suit. The command object would no longer be a dependency. At which point invoking a command is no different than using call_user_func, which is why the abstraction for a self handling command exists. If native php callable types are then prioritized over Commands, a self invoking command is then simply a callable object. The reason it gets flagged as a Self Handling Command is because unless the Bus supports call_user_func, then there is a hole in the abstraction.

Matthias Noback

I don't think self-handling commands are a great idea, because of the great contradictions in them: 1. You turn an immutable service into a mutable data transfer object (or vice versa) and 2. You mingle the eternal logic of handling a command with the temporal data inside a command.