Command Bus
The Command Bus plugin dispatches commands (write operations) to their corresponding handlers, decoupling the issuer from the handler implementation.
Two adapters are available:
- SyncCommandBus executes commands synchronously with automatic handler resolution.
- TransactionalCommandBus wraps command execution in a database transaction (decorator pattern).
Why Use It
In CQRS architecture, write operations are represented as commands. The Command Bus provides a single dispatch point that resolves the appropriate handler based on naming convention (CreateBookCommand → CreateBookHandler). This separation enables middleware insertion (transactions, logging) without modifying business logic.
Usage
The bus dispatches a command to its handler:
$command = new CreateBookCommand($id, $title, $author, $isbn);
$this->commandBus->dispatch($command);
Commands are immutable data objects representing the intention to change state:
final readonly class CreateBookCommand implements CommandInterface
{
public function __construct(
public IdInterface $id,
public string $title,
public string $author,
public string $isbn
) {}
}
Handlers process commands and return nothing (void):
public function handle(CommandInterface $command): void
{
$book = new Book($command->id, ...);
$this->bookRepository->save($book);
$this->eventBus->dispatch(new BookCreatedEvent(...));
}
Testing
The SyncCommandBus can be instantiated directly in tests. For integration testing, handlers are typically tested in isolation by mocking the repository and event bus dependencies.
See Also
- CQRS - Command Bus enables CQRS pattern
- Bus Mode - Primary architectural pattern
- Commands & Handlers - What the bus dispatches
- Transaction - TransactionalCommandBus decorator