The What
A command bus is an infrastructure object that manages the relationship between Commands and Command Handlers. Command Bus’s will handle commands, and then forward the command to the appropriate handler.
The Why
This infrastructure class improves loose coupling by enabling both the Command and CommandHandler to not know about each other’s implementation details. This abstraction improves separation of concerns and loose coupling.
Terminology
Command Bus - The object that manages the relationship between Command and Command Handler.
Command - A DTO that represents a state change the system should take.
Command Handler - An object that executes the command
Sample Code
Example JS Code - https://gist.github.com/geggleto/f072939ba9adb2ea938caacb23919570
Conclusion
Like the Event Bus a command bus serves a vital purpose of good system design for large complex systems by enabling loose coupling and adhering to separation of concerns. The main difference between a Command Bus and Event Bus is that Command Buses are strictly only ever 1-1 between Commands and Handlers. While there’s no theatrical reason why you cannot have “multiple handlers” for a command, it’s largely seen as an anti-pattern because if a handler is performing more than 1 operation it should be split out as per Single Responsibility Principles. This can be done using Events and other commands. The primary reason that I reference for this is for fault tolerance and idempotence.
Idempotency
Idempotency is the property of certain operations in mathematics and computer science where by the operation can be applied multiple times without changing the result beyond the initial application. An example of this would be if the User clicks Pay Now. You should only ever charge them once, even if they hit it again. This can be achieved by using the Command/Command Handler pattern and using a unique id of this transaction.
An example of Idempotency in the wild would be StripeJS’ Charge API; where you may pass an “Idempotency Id”. This ID makes sure the user is only ever charged once.