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

Rabbitmq Bundle Consumer Generator Laravel Package

edfa3ly-backend/rabbitmq-bundle-consumer-generator

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require edfa3ly-backend/rabbitmq-bundle-consumer-generator
    

    Ensure php-amqplib/rabbitmq-bundle is already installed (this package extends it).

  2. Register the Bundle Add to config/bundles.php:

    return [
        // ...
        Edfa3ly\RabbitMQBundleConsumerGenerator\Edfa3lyRabbitMQBundleConsumerGeneratorBundle::class => ['all' => true],
    ];
    
  3. First Use Case: Dynamic Consumer Creation Inject GeneratorWrapper into a service (e.g., a command or event listener) and define a consumer:

    use Edfa3ly\RabbitMQBundleConsumerGenerator\GeneratorWrapper;
    use Edfa3ly\RabbitMQBundleConsumerGenerator\ConsumerSkeleton;
    
    class CreateConsumersCommand
    {
        public function __construct(private GeneratorWrapper $wrapper) {}
    
        public function handle()
        {
            $consumer = new ConsumerSkeleton();
            $consumer->setName('order_processor')
                     ->setQueueRoutingKeys(['order.created'])
                     ->setExchangeType('fanout')
                     ->setService('App\Services\OrderProcessorService');
    
            $this->wrapper->generate($consumer, __DIR__.'/../config/rabbitmq/consumers');
        }
    }
    

Implementation Patterns

Core Workflow

  1. Define Consumers Programmatically Use ConsumerSkeleton to configure consumers dynamically (e.g., in a migration, command, or service bootstrapping):

    $consumer = new ConsumerSkeleton();
    $consumer->setName('user_notifier')
             ->setQueue('user_events')
             ->setExchange('notifications')
             ->setExchangeType('direct')
             ->setRoutingKeys(['user.registered', 'user.updated'])
             ->setService('App\Services\UserNotifier')
             ->setQos(10) // Prefetch count
             ->setAutoAck(false);
    
  2. Generate YAML Config Call GeneratorWrapper::generate() to write the consumer to your RabbitMQ config directory (default: config/rabbitmq/consumers/):

    $this->wrapper->generate($consumer, $customPath = null);
    
    • Output: Generates a YAML file like order_processor.yml with the consumer’s configuration.
  3. Integration with RabbitMQ Bundle The generated YAML adheres to php-amqplib/rabbitmq-bundle’s format. Ensure your config/rabbitmq.yaml includes:

    consumers:
        path: "%kernel.project_dir%/config/rabbitmq/consumers"
        file_name_pattern: "%%name%%.yml"
    
  4. Dynamic Consumer Lifecycle

    • Add/Update: Generate consumers during deployment (e.g., via a post-install command).
    • Remove: Delete the YAML file manually or extend the bundle to handle cleanup.

Advanced Patterns

  • Environment-Specific Consumers Use the GeneratorWrapper in a Bootstrap service to generate consumers conditionally:

    if (app()->environment('production')) {
        $this->wrapper->generate($highPriorityConsumer);
    }
    
  • Consumer Templates Create a base ConsumerSkeleton class with default values (e.g., autoAck: false) to avoid repetition:

    class BaseConsumer extends ConsumerSkeleton
    {
        public function __construct()
        {
            $this->setAutoAck(false);
        }
    }
    
  • Event-Driven Generation Trigger consumer generation on domain events (e.g., ConsumerAdded):

    public function handle(ConsumerAdded $event)
    {
        $consumer = new ConsumerSkeleton();
        $consumer->setName($event->name)->setService($event->service);
        $this->wrapper->generate($consumer);
    }
    

Gotchas and Tips

Pitfalls

  1. YAML Overwrite Risks

    • Issue: generate() overwrites existing YAML files without warning.
    • Fix: Check for file existence first or implement a merge strategy:
      if (!file_exists($path)) {
          $this->wrapper->generate($consumer, $path);
      }
      
  2. Service Class Requirements

    • Issue: The generated YAML expects the service field to point to a valid Laravel service container class. If the class doesn’t exist, the consumer fails silently.
    • Fix: Validate the service class exists before generation:
      if (!class_exists($consumer->getService())) {
          throw new \RuntimeException("Service {$consumer->getService()} not found.");
      }
      
  3. Queue/Exchange Name Conflicts

    • Issue: Duplicate queue/exchange names in YAML can cause RabbitMQ to throw errors.
    • Fix: Add validation in your ConsumerSkeleton:
      public function setQueue($name)
      {
          if (strpos($name, '.') !== false) {
              throw new \InvalidArgumentException('Queue names cannot contain dots.');
          }
          $this->queue = $name;
          return $this;
      }
      
  4. Bundle Compatibility

    • Issue: The package is unmaintained (last release 2019) and may not work with newer Laravel/RabbitMQ Bundle versions.
    • Fix: Test thoroughly with your stack. Fork and update dependencies if needed.

Debugging Tips

  1. Verify Generated YAML After generation, validate the YAML matches expectations:

    php artisan rabbitmq:validate
    

    (If the command doesn’t exist, manually check config/rabbitmq/consumers/.)

  2. Check RabbitMQ Logs If consumers aren’t working, inspect RabbitMQ server logs for connection/queue errors.

  3. Enable Debugging Temporarily enable debug: true in config/rabbitmq.yaml to log consumer generation:

    consumers:
        debug: true
    

Extension Points

  1. Customize YAML Output Extend ConsumerSkeleton to add custom fields or modify the YAML structure:

    class CustomConsumer extends ConsumerSkeleton
    {
        private $customField;
    
        public function setCustomField($value)
        {
            $this->customField = $value;
            return $this;
        }
    
        public function getCustomField()
        {
            return $this->customField;
        }
    }
    

    Then override the generator’s generate() method or use a custom template.

  2. Add Consumer Metadata Store additional metadata (e.g., created_at, environment) in the YAML:

    $consumer->setMetadata(['environment' => app()->environment()]);
    
  3. Hook into Generation Subscribe to the rabbitmq.consumer.generated event (if the bundle supports it) or wrap GeneratorWrapper to add pre/post-generation logic:

    $this->wrapper->generate($consumer, $path);
    // Post-generation logic here
    
  4. Support for Multiple Exchanges Extend the bundle to handle consumers with multiple exchanges/routing keys dynamically:

    $consumer->setExchanges([
        ['name' => 'exchange1', 'type' => 'direct', 'routing_keys' => ['key1']],
        ['name' => 'exchange2', 'type' => 'fanout'],
    ]);
    
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle