Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Message Bus Laravel Package

simple-bus/message-bus

Generic PHP interfaces and utilities for building message buses such as command buses and event buses. Provides reusable components to dispatch messages through middleware and handlers, forming the foundation for CQRS-style messaging in your app.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup in Laravel

  1. Installation

    composer require simple-bus/message-bus
    

    No Laravel-specific package exists, so use the core simple-bus/message-bus package.

  2. Define a Message Create a simple DTO (Data Transfer Object) for your message:

    // app/Domain/Commands/SendEmail.php
    namespace App\Domain\Commands;
    
    class SendEmail
    {
        public function __construct(
            public string $email,
            public string $subject,
            public string $body
        ) {}
    }
    
  3. Create a Handler Implement SimpleBus\Message\Handler\MessageHandlerInterface:

    // app/Domain/Handlers/SendEmailHandler.php
    namespace App\Domain\Handlers;
    
    use App\Domain\Commands\SendEmail;
    use SimpleBus\Message\Handler\MessageHandlerInterface;
    
    class SendEmailHandler implements MessageHandlerInterface
    {
        public function handle(SendEmail $message)
        {
            // Logic to send email
            mail($message->email, $message->subject, $message->body);
        }
    }
    
  4. Register the Handler Use Laravel's service container to bind the handler:

    // app/Providers/AppServiceProvider.php
    use App\Domain\Handlers\SendEmailHandler;
    use SimpleBus\Message\Handler\MessageHandlerInterface;
    
    public function register()
    {
        $this->app->bind(
            MessageHandlerInterface::class,
            SendEmailHandler::class
        );
    }
    
  5. Dispatch a Message Use a MessageBus instance (injected via Laravel's container):

    use SimpleBus\Message\Bus\MessageBus;
    
    public function dispatchEmail()
    {
        $bus = app(MessageBus::class);
        $bus->dispatch(new SendEmail('user@example.com', 'Hello', 'World!'));
    }
    

Implementation Patterns

Command Bus Workflow

  1. Separation of Concerns

    • Use commands for actions (e.g., CreateUser, SendEmail).
    • Keep handlers stateless and focused on a single responsibility.
  2. Middleware Integration Leverage middleware for cross-cutting concerns (logging, validation, retries):

    // app/Providers/AppServiceProvider.php
    use SimpleBus\Message\Bus\MessageBus;
    use SimpleBus\Message\Middleware\Middleware;
    
    public function register()
    {
        $bus = $this->app->make(MessageBus::class);
        $bus->addMiddleware(new class implements Middleware {
            public function handle($message, callable $next)
            {
                // Pre-processing (e.g., logging)
                $result = $next($message);
                // Post-processing
                return $result;
            }
        });
    }
    
  3. Event Bus for Side Effects

    • Dispatch events after commands for asynchronous workflows:
    // Inside SendEmailHandler
    $bus->dispatch(new EmailSent($message->email));
    
  4. Laravel-Specific Integration

    • Use Laravel's Bus facade or inject MessageBus directly:
    use Illuminate\Support\Facades\Bus;
    
    Bus::dispatch(new SendEmail(...));
    
  5. Testing

    • Mock the MessageBus or use Bus::fake() for testing:
    use Illuminate\Support\Facades\Bus;
    
    Bus::fake();
    $bus->dispatch(new SendEmail(...));
    Bus::assertDispatched(SendEmail::class);
    

Gotchas and Tips

Pitfalls

  1. Handler Registration

    • Issue: Forgetting to bind handlers to MessageHandlerInterface in the container.
    • Fix: Use Laravel's bind() or when() for conditional binding.
  2. Circular Dependencies

    • Issue: Handlers depending on the MessageBus can cause circular references.
    • Fix: Avoid injecting MessageBus into handlers. Use Laravel's Bus facade or resolve it via the container only when needed.
  3. Middleware Order

    • Issue: Middleware execution order matters. Prepend for early execution, add for late execution.
    • Fix: Use addMiddleware() for append and prependMiddleware() for prepend.
  4. Exception Handling

    • Issue: Unhandled exceptions in handlers may lock the bus (pre-1.0.1).
    • Fix: Wrap handler logic in try-catch or use middleware to log/handle exceptions.
  5. Message Immutability

    • Issue: Modifying message properties after dispatch can cause inconsistencies.
    • Fix: Treat messages as immutable DTOs. Use constructor injection for all required data.

Debugging Tips

  1. Logging Middleware Use the built-in logging middleware for visibility:

    $bus->addMiddleware(new \SimpleBus\Message\Middleware\LoggingMiddleware());
    
  2. Handler Discovery

    • If handlers aren’t found, verify:
      • The handler implements MessageHandlerInterface.
      • The handler is properly bound in the container.
      • The message type matches the handler’s method signature.
  3. Performance

    • Issue: High latency in message processing.
    • Fix: Use async queues (e.g., Laravel Queues) for non-critical commands/events.

Extension Points

  1. Custom Middleware Extend functionality with middleware (e.g., rate limiting, circuit breakers):

    $bus->addMiddleware(new class implements Middleware {
        public function handle($message, callable $next)
        {
            if ($this->shouldSkip($message)) {
                return $next($message);
            }
            throw new \RuntimeException('Skipped!');
        }
    });
    
  2. Message Validation Use middleware to validate messages before handling:

    $bus->addMiddleware(new class implements Middleware {
        public function handle($message, callable $next)
        {
            if (!filter_var($message->email, FILTER_VALIDATE_EMAIL)) {
                throw new \InvalidArgumentException('Invalid email!');
            }
            return $next($message);
        }
    });
    
  3. Retry Logic Implement retry middleware for transient failures:

    $bus->addMiddleware(new \SimpleBus\Message\Middleware\RetryMiddleware());
    
  4. Laravel Queues Integration Combine with Laravel Queues for async processing:

    // Dispatch to queue
    Bus::dispatch(new SendEmail(...))->onQueue('emails');
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky