Module Communication Bus
The Module Communication Bus is a modular communication infrastructure for the Planet project, designed based on Command Query Separation (CQS) and CQRS patterns. It provides a robust, decoupled way for modules to communicate with each other without direct dependencies.
What is the Bus System?
The Bus System is a communication layer that enables different modules of the application to interact with each other through a standardized interface. It implements the Command Query Separation (CQS) principle, which states that methods should either perform an action (Command) or return data (Query), but not both.
The Bus System is a core architectural component that enforces clean separation of concerns and promotes loose coupling between modules.
Key Features
- Complete Command and Query Separation: Commands never return data, Queries never change state
- Loose Coupling: Modules have no direct dependencies on each other
- Explicit Registration: Handlers are explicitly registered without auto-discovery
- Type Safety: Full type safety with PHP 8.1+ features
- Comprehensive Error Handling: Standardized error handling across all modules
- High Testability: Easy to mock handlers and test components independently
When to Use the Bus System
You should use the Bus System when:
- You need to communicate between different modules
- You want to enforce a clear separation between commands and queries
- You need a standardized way to handle errors and responses
- You want to improve testability of your code
- You need to maintain loose coupling between components
Core Components
The Bus System consists of the following core components:
Contracts (Interfaces)
BusMessage: Base interface for all messagesCommandInterface: Marker interface for CommandsQueryInterface: Marker interface for QueriesBusResponseInterface: Standard response structureCommandBusInterface: Contract for CommandBusQueryBusInterface: Contract for QueryBus
Implementations
InMemoryCommandBus: Synchronous CommandBus implementationInMemoryQueryBus: Synchronous QueryBus implementationBusSuccessResponse: Success response with immutable value object patternBusErrorResponse: Error response with validation
Quick Start
Here's a quick example of how to use the Bus System:
// Controller
class UserController extends Controller
{
public function __construct(
private readonly CommandBusInterface $commandBus,
private readonly QueryBusInterface $queryBus
) {}
public function show(int $id): JsonResponse
{
$query = new GetUserByIdQuery($id);
$response = $this->queryBus->dispatch($query);
if ($response->isSuccess()) {
return response()->json(['data' => $response->getData()]);
}
return response()->json(['error' => $response->getErrorMessage()], 404);
}
public function store(Request $request): JsonResponse
{
$command = new CreateUserCommand(
$request->input('name'),
$request->input('email'),
$request->input('password')
);
$this->commandBus->dispatch($command);
return response()->json(['message' => 'User created'], 201);
}
}
Next Steps
To learn more about the Bus System, check out the following guides:
- Architecture - Detailed explanation of the Bus System architecture
- Implementation Guide - How to implement the Bus System in your modules
- Best Practices - Coding standards and best practices
- Examples - Practical examples of using the Bus System