In the world of service oriented architectures and CQRS style processes there is a tendancy for nearly everything to raise events. Going back a few years however, before REST became fashionable many interactions were by RPC and often the result of processing commands from a queue.
So when did commands become an anti-pattern? Well of course, they never did. These days we just have to understand when it’s more appropriate to send a command or raise an event.
Here’s a table to help you decide what you should be using:
|An event is all about something that has already happened||A command is all about something that the originating service wants to happen (although it might not be successful)|
|A service raising an event doesn’t care what happens to it. Something consuming an event is not critical to the service’s function.||A service sending a command needs that command to be processed as part of it’s functionality.|
|An event could be consumed by one, many or no consumers.||A command is intended for one specific consumer.|
|An event can suggest loose coupling between services.||A command definitely indicates tight coupling – the originating service knows about the command target.|
|A service prevented from raising an event can only report that the event was not raised.||A service prevented from sending a command can report the failure to a team with specific domain knowledge about what will happen down stream if the command is not processed. The service may be designed to fail its own process if the command fails.|
A really good example of the right use of an event is communicating between services within a bounded context that something has happened. The originating service will have successfully completed its function before raising the event. Consumers of the event do something else in addition that the originating service doesn’t really care about.
A good example of the right use of a command is where two different platforms need to be kept in sync with each other. When data is updated in one system a sync command is sent to update the other. If something stops that command getting sent (e.g. an auth issue between the service and a message queue) then the service can react and alert people to the issue, or it may be that the update in the originating service needs to fail.
Both events and commands are important in a distributed system. Using them in the right places makes your intent much clearer and helps keep your system structured.