The contract for middleware components in the cmd-bus pipeline system.
MiddlewareInterface defines the standard interface for middleware that can intercept and process commands before they reach their final handlers. Middleware enables cross-cutting concerns.
interface MiddlewareInterface
{
public function process(CommandInterface $command, CommandHandlerInterface $handler): mixed;
}Processes a command and optionally delegates to the next handler in the pipeline.
Parameters:
$command- The command being processed$handler- The next handler in the pipeline (could be another middleware or the final handler)
Returns:
mixed- The result of processing (typically from calling$handler->handle($command))
Middleware serves to:
- Implement Cross-Cutting Concerns - Handle aspects that span multiple commands
- Pipeline Composition - Allow flexible composition of processing steps
- Separation of Concerns - Keep business logic separate from infrastructure concerns
use Laminas\ServiceManager\Factory\FactoryInterface;
use Psr\Container\ContainerInterface;
class LoggingMiddlewareFactory implements FactoryInterface
{
public function __invoke(
ContainerInterface $container,
$requestedName,
array $options = null
): LoggingMiddleware {
return new LoggingMiddleware(
$container->get(LoggerInterface::class)
);
}
}Unless you're intentionally short-circuiting the pipeline:
public function process(CommandInterface $command, CommandHandlerInterface $handler): mixed
{
// Do pre-processing
$result = $handler->handle($command);
// Do post-processing
return $result;
}Don't swallow exceptions unless you have a good reason:
try {
return $handler->handle($command);
} catch (\Throwable $e) {
// Log or handle the exception
$this->logger->error('Error', ['exception' => $e]);
throw $e; // Re-throw the exception
}Create specific interfaces for commands that need special handling:
interface AuthenticatedCommandInterface extends CommandInterface
{
public function getRequiredPermission(): string;
}Each middleware should have a single responsibility:
// ✅ Good - focused on logging
class LoggingMiddleware implements MiddlewareInterface
// ❌ Bad - does too many things
class LoggingValidationCachingMiddleware implements MiddlewareInterface- MiddlewarePipe - Pipeline that manages middleware execution
- PreCommandHandlerMiddleware - Middleware for pre-processing commands
- CommandHandlerMiddleware - Final middleware for command execution
- PostCommandHandlerMiddleware - Middleware for post-processing results
- CommandInterface - Commands processed by middleware
- CommandHandlerInterface - Handlers called by middleware