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

averor/message-bus

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require averor/message-bus
    

    Publish the config (if needed):

    php artisan vendor:publish --provider="Averor\MessageBus\MessageBusServiceProvider"
    
  2. Define a Command Create a command class (e.g., app/Commands/ProcessOrder.php):

    namespace App\Commands;
    
    use Averor\MessageBus\Command;
    
    class ProcessOrder implements Command
    {
        public function __construct(
            public string $orderId,
            public float $amount
        ) {}
    }
    
  3. Define a Handler Create a handler (e.g., app/Handlers/ProcessOrderHandler.php):

    namespace App\Handlers;
    
    use App\Commands\ProcessOrder;
    use Averor\MessageBus\CommandHandler;
    
    class ProcessOrderHandler implements CommandHandler
    {
        public function handle(ProcessOrder $command)
        {
            // Business logic here
            return "Order {$command->orderId} processed for {$command->amount}";
        }
    }
    
  4. Dispatch the Command In a controller or service:

    use Averor\MessageBus\MessageBus;
    
    class OrderController extends Controller
    {
        public function __construct(private MessageBus $bus) {}
    
        public function store()
        {
            $result = $this->bus->dispatch(new ProcessOrder('123', 100.00));
            return response()->json(['success' => $result]);
        }
    }
    
  5. Register Handlers Bind handlers in a service provider (e.g., AppServiceProvider):

    public function boot()
    {
        $this->app->bind(
            \App\Handlers\ProcessOrderHandler::class,
            fn() => new \App\Handlers\ProcessOrderHandler()
        );
    }
    

Implementation Patterns

Convention-Based Workflow

  • Naming Conventions

    • Commands: *Command (e.g., CreateUserCommand).
    • Handlers: *Handler (e.g., CreateUserHandler).
    • Events: *Event (if using event sourcing).
    • Place commands in app/Commands/ and handlers in app/Handlers/.
  • Automatic Handler Resolution The package auto-resolves handlers based on command class names (e.g., ProcessOrderProcessOrderHandler). Override via explicit binding if needed.

Integration with Laravel Features

  1. Middleware for Commands Apply middleware to commands (e.g., auth, validation):

    $this->bus->dispatch(new ProcessOrder('123', 100.00))
        ->withMiddleware(Authenticate::class)
        ->withMiddleware(ValidateOrder::class);
    
  2. Queueable Commands Dispatch commands to queues:

    $this->bus->dispatch(new ProcessOrder('123', 100.00))->delay(5)->onQueue('orders');
    
  3. Event Sourcing (Optional) Extend Averor\MessageBus\Event and use MessageBus::publish() for events:

    $this->bus->publish(new OrderCreatedEvent('123'));
    

Testing

  • Mock Handlers Use Laravel’s mocking to test command dispatch:

    $handler = Mockery::mock(\App\Handlers\ProcessOrderHandler::class);
    $this->app->instance(\App\Handlers\ProcessOrderHandler::class, $handler);
    
    $result = $this->bus->dispatch(new ProcessOrder('123', 100.00));
    $handler->shouldHaveReceived('handle');
    
  • Command Testing Test commands in isolation:

    $command = new ProcessOrder('123', 100.00);
    $handler = new ProcessOrderHandler();
    $result = $handler->handle($command);
    $this->assertEquals("Order 123 processed for 100.00", $result);
    

Gotchas and Tips

Pitfalls

  1. Handler Not Found

    • Issue: Command dispatched but no handler found.
    • Fix: Ensure the handler class exists and follows the naming convention (*Handler). Explicitly bind if custom:
      $this->app->bind(
          \App\Handlers\CustomProcessOrderHandler::class,
          fn() => new \App\Handlers\CustomProcessOrderHandler()
      );
      
  2. Middleware Order

    • Issue: Middleware runs in reverse order of registration.
    • Fix: Register middleware in the desired execution order:
      $this->bus->dispatch($command)
          ->withMiddleware(FirstMiddleware::class)
          ->withMiddleware(SecondMiddleware::class); // Runs first
      
  3. Circular Dependencies

    • Issue: Handlers depending on commands or other handlers.
    • Fix: Avoid circular dependencies. Use interfaces or abstract classes for loose coupling.
  4. Queue Failures

    • Issue: Failed jobs in the queue.
    • Fix: Implement ShouldQueue interface for commands and handle failures in FailedJob observer:
      use Illuminate\Bus\Queueable;
      use Illuminate\Contracts\Queue\ShouldQueue;
      
      class ProcessOrder implements Command, ShouldQueue
      {
          use Queueable;
          // ...
      }
      

Debugging Tips

  • Log Dispatches Enable logging in config/message-bus.php:

    'logging' => true,
    

    Check Laravel logs for dispatched commands/handlers.

  • Handler Execution Flow Use tap() to inspect command/handler state:

    $this->bus->dispatch($command)->tap(function ($result) {
        \Log::info('Command result:', ['result' => $result]);
    });
    

Extension Points

  1. Custom Dispatcher Extend Averor\MessageBus\Dispatcher to add logic (e.g., retry logic, metrics):

    class CustomDispatcher extends Dispatcher
    {
        protected function beforeHandle($command, $handler)
        {
            // Add pre-handling logic
        }
    }
    

    Bind it in AppServiceProvider:

    $this->app->bind(
        \Averor\MessageBus\Dispatcher::class,
        fn() => new \App\CustomDispatcher()
    );
    
  2. Dynamic Handler Resolution Override resolveHandler() in a custom dispatcher for dynamic resolution:

    protected function resolveHandler($command)
    {
        return new \App\Handlers\DynamicHandler($command);
    }
    
  3. Event Listeners Attach listeners to commands/events:

    $this->bus->dispatch($command)
        ->withListener(\App\Listeners\LogCommand::class);
    

Performance Considerations

  • Avoid Heavy Handlers Offload heavy processing to queues or background jobs.
  • Batch Processing Use MessageBus::batch() for bulk operations:
    $this->bus->batch([
        new ProcessOrder('1', 100),
        new ProcessOrder('2', 200),
    ])->dispatch();
    
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.
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle
dmstr/api-platform-utils-bundle
dmstr/api-configuration-bundle
chrisdev/ux-components
baks-dev/finances
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle