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

Symfony Bridge Laravel Package

simple-bus/symfony-bridge

Symfony integration bridge for SimpleBus/MessageBus. Provides CommandBusBundle, EventBusBundle, and DoctrineORMBridgeBundle to wire command and event buses into your Symfony app, with docs and upgrade guide.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require simple-bus/symfony-bridge
    

    Enable the required bundles in config/bundles.php:

    return [
        // ...
        SimpleBus\SymfonyBridge\CommandBusBundle\CommandBusBundle::class => ['all' => true],
        SimpleBus\SymfonyBridge\EventBusBundle\EventBusBundle::class => ['all' => true],
    ];
    
  2. Configure the Bus: Add a simple_bus configuration block in config/packages/simple_bus.yaml:

    simple_bus:
        command_bus:
            messenger: true  # Use Symfony Messenger (default)
            # OR
            # simple_bus: true  # Use SimpleBus directly
        event_bus:
            messenger: true
    
  3. First Use Case:

    • Command Bus: Dispatch a command in a controller/service:
      use App\Command\CreateUserCommand;
      
      public function handle(CreateUserCommand $command)
      {
          // Logic here
      }
      
      // Dispatch
      $this->bus->dispatch(new CreateUserCommand('John Doe'));
      
    • Event Bus: Publish an event:
      use App\Event\UserCreatedEvent;
      
      $this->eventBus->publish(new UserCreatedEvent($userId));
      
  4. Handlers: Register handlers as services with the simple_bus.handler tag:

    services:
        App\CommandHandler\CreateUserCommandHandler:
            tags: ['simple_bus.handler']
    

Implementation Patterns

Core Workflows

Command Bus Workflow

  1. Define Commands:

    namespace App\Command;
    class CreateUserCommand {
        public function __construct(public string $name) {}
    }
    
  2. Handle Commands:

    namespace App\CommandHandler;
    use App\Command\CreateUserCommand;
    
    class CreateUserCommandHandler {
        public function __invoke(CreateUserCommand $command) {
            // Business logic
        }
    }
    
  3. Dispatch Commands:

    $this->bus->dispatch(new CreateUserCommand('Alice'));
    
  4. Async Dispatch (Messenger): Enable messenger: true in config to leverage Symfony Messenger’s async transport.

Event Bus Workflow

  1. Define Events:

    namespace App\Event;
    class UserCreatedEvent {
        public function __construct(public int $userId) {}
    }
    
  2. Handle Events:

    namespace App\EventHandler;
    use App\Event\UserCreatedEvent;
    
    class UserCreatedEventHandler {
        public function __invoke(UserCreatedEvent $event) {
            // Side effects (e.g., notifications)
        }
    }
    
  3. Publish Events:

    $this->eventBus->publish(new UserCreatedEvent($userId));
    
  4. Event Subscribers: Use Symfony’s kernel.event_listener tag for event listeners:

    services:
        App\EventListener\UserCreatedListener:
            tags: ['kernel.event_listener', { event: 'app.user_created', method: 'onUserCreated' }]
    

Integration Tips

  1. Dependency Injection: Inject the bus directly into services:

    use SimpleBus\SymfonyBridge\CommandBus\CommandBusInterface;
    
    public function __construct(private CommandBusInterface $bus) {}
    
  2. Middleware: Add middleware to the bus (e.g., logging, validation):

    simple_bus:
        command_bus:
            middleware: ['App\Middleware\LogCommandMiddleware']
    
  3. Doctrine ORM Bridge: For command/event handlers requiring Doctrine:

    use SimpleBus\SymfonyBridge\DoctrineORMBridge\DoctrineORMBus;
    
    public function __construct(
        DoctrineORMBus $bus,
        EntityManagerInterface $em
    ) {}
    
  4. Testing: Mock the bus in tests:

    $bus = $this->createMock(CommandBusInterface::class);
    $bus->expects($this->once())->method('dispatch');
    $this->app->instance(CommandBusInterface::class, $bus);
    

Gotchas and Tips

Pitfalls

  1. Circular Dependencies: Avoid circular dependencies between commands/events and their handlers. Use DTOs (Data Transfer Objects) for complex data.

  2. Handler Registration: Forgetting to tag handlers with simple_bus.handler will result in silent failures. Verify with:

    php bin/console debug:container simple_bus.handler
    
  3. Messenger vs. SimpleBus:

    • Messenger: Async by default, requires messenger: true in config.
    • SimpleBus: Synchronous by default (simple_bus: true). Choose based on needs.
  4. Event Ordering: Events are published synchronously by default. For async publishing, combine with Symfony Messenger or a queue system.

  5. Doctrine Transactions: If using DoctrineORMBridgeBundle, ensure transactions are managed explicitly in handlers to avoid issues:

    $em->beginTransaction();
    try {
        $this->bus->dispatch($command);
        $em->commit();
    } catch (\Exception $e) {
        $em->rollback();
        throw $e;
    }
    

Debugging

  1. Handler Not Called:

    • Check for typos in handler class names or tags.
    • Verify the bus is properly injected (use debug:container).
    • Enable debug mode (APP_DEBUG=true) to see unhandled exceptions.
  2. Middleware Issues: Debug middleware by temporarily removing them or logging their execution:

    public function handle($message, callable $next) {
        \Symfony\Component\Debug\Debug::info('Middleware executed');
        return $next($message);
    }
    
  3. Configuration Errors: Validate simple_bus.yaml syntax and available options. Use:

    php bin/console config:dump-reference simple_bus
    

Extension Points

  1. Custom Middleware: Create middleware for cross-cutting concerns (e.g., auth, metrics):

    namespace App\Middleware;
    use SimpleBus\Message\Bus\Middleware\Middleware;
    
    class AuthMiddleware implements Middleware {
        public function handle($message, callable $next) {
            if (!$this->isAuthenticated()) {
                throw new \RuntimeException('Unauthenticated');
            }
            return $next($message);
        }
    }
    
  2. Dynamic Handlers: Use Symfony’s compiler passes or runtime logic to dynamically register handlers (e.g., based on user roles).

  3. Event Dispatcher Bridge: Combine with Symfony’s EventDispatcher for hybrid event handling:

    use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
    
    $dispatcher->addListener('app.user_created', function (UserCreatedEvent $event) {
        $this->eventBus->publish($event);
    });
    
  4. Async Command Handling: For long-running commands, pair with Symfony Messenger’s transports (e.g., Doctrine, Redis):

    framework:
        messenger:
            transports:
                async: '%env(MESSENGER_TRANSPORT_DSN)%'
    
  5. Testing Utilities: Extend the package’s test utilities for custom assertions:

    $this->assertBusWasCalledWith($bus, new CreateUserCommand('Bob'));
    
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