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

Ecentria Apievents Bundle Laravel Package

ecentria/ecentria-apievents-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the bundle via Composer:

    composer require ecentria/ecentria-apievents-bundle
    

    Enable it in config/bundles.php:

    return [
        // ...
        Ecentria\APIEventsBundle\EcentriaAPIEventsBundle::class => ['all' => true],
    ];
    
  2. Configuration Publish the default config:

    php artisan config:dump
    

    Update config/packages/ecentria_api_events.yaml with your RabbitMQ connection details:

    ecentria_api_events:
        rabbitmq:
            host: 'localhost'
            port: 5672
            user: 'guest'
            password: 'guest'
            vhost: '/'
            exchange: 'api_events'
            queue: 'api_events_queue'
    
  3. First Use Case: Listening to Events Create a Symfony event listener to handle domain events:

    namespace App\EventListener;
    
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    use Ecentria\APIEventsBundle\Event\DomainEvent;
    
    class MyEventSubscriber implements EventSubscriberInterface
    {
        public static function getSubscribedEvents()
        {
            return [
                DomainEvent::class => 'onDomainEvent',
            ];
        }
    
        public function onDomainEvent(DomainEvent $event)
        {
            // Handle the event payload
            $data = $event->getData();
            // ...
        }
    }
    
  4. Run the Consumer Start the RabbitMQ consumer in a separate terminal:

    php bin/console ecentria:api-events:consume
    

Implementation Patterns

Core Workflow

  1. Publishing Events Use the bundle’s EventPublisher service to dispatch domain events to RabbitMQ:

    use Ecentria\APIEventsBundle\Service\EventPublisher;
    
    class MyService
    {
        public function __construct(private EventPublisher $publisher) {}
    
        public function triggerEvent()
        {
            $this->publisher->publish('user.created', ['id' => 123]);
        }
    }
    
  2. Event Structure Events are JSON-serialized payloads with a type (e.g., user.created) and data:

    {
        "type": "user.created",
        "data": { "id": 123, "name": "John Doe" }
    }
    
  3. Consumer Integration

    • Run the consumer as a daemon (e.g., via supervisord or systemd).
    • For testing, mock the RabbitMQ connection or use a test queue:
      # config/packages/test/ecentria_api_events.yaml
      ecentria_api_events:
          rabbitmq:
              host: 'localhost'
              vhost: '/test'
      
  4. Event Dispatching The bundle automatically converts RabbitMQ messages into Symfony DomainEvent objects. Subscribe to events in your services:

    // app/config/services.yaml
    services:
        App\EventListener\MyEventSubscriber:
            tags:
                - { name: kernel.event_subscriber }
    
  5. Batch Processing For high-throughput scenarios, implement a batch consumer by extending the base consumer:

    use Ecentria\APIEventsBundle\Consumer\BaseConsumer;
    
    class BatchConsumer extends BaseConsumer
    {
        protected function processMessage($message)
        {
            // Process in batches (e.g., every 100 messages)
        }
    }
    

Gotchas and Tips

Pitfalls

  1. RabbitMQ Connection Issues

    • Symptom: Consumer fails silently or throws ConnectionException.
    • Fix: Verify credentials in config/packages/ecentria_api_events.yaml and ensure RabbitMQ is running:
      rabbitmqctl status
      
    • Debug: Enable logging in config/packages/monolog.yaml:
      handlers:
          rabbitmq:
              type: stream
              path: "%kernel.logs_dir%/rabbitmq.log"
              level: debug
      
  2. Event Deserialization Errors

    • Symptom: JsonException when processing messages.
    • Fix: Validate the event payload structure. Use a custom validator:
      use Ecentria\APIEventsBundle\Validator\EventValidator;
      
      class MyValidator extends EventValidator
      {
          public function validate($data)
          {
              if (!isset($data['type'])) {
                  throw new \RuntimeException('Missing event type');
              }
          }
      }
      
      Register it in services.yaml:
      services:
          App\Validator\MyValidator:
              tags: [ecentria_api_events.validator]
      
  3. Duplicate Events

    • Cause: RabbitMQ acknowledgments (ack) may fail if the consumer crashes.
    • Fix: Enable manual acknowledgments in the consumer:
      // In your custom consumer
      $this->channel->basic_qos(null, 1, null); // Prefetch 1 message
      $this->channel->basic_consume($queue, '', false, true, false, false, [$this, 'handleDelivery']);
      
  4. Performance Bottlenecks

    • Symptom: Slow event processing under load.
    • Fix:
      • Increase RabbitMQ prefetch count (e.g., basic_qos(null, 100)).
      • Use async processing with Symfony Messenger:
        use Symfony\Component\Messenger\MessageBusInterface;
        
        class MyService
        {
            public function __construct(private MessageBusInterface $bus) {}
        
            public function handleEvent(DomainEvent $event)
            {
                $this->bus->dispatch(new AsyncEvent($event->getData()));
            }
        }
        

Tips

  1. Testing

    • Use PHPUnit to test event subscribers:
      public function testEventSubscriber()
      {
          $event = new DomainEvent(['type' => 'test.event', 'data' => []]);
          $subscriber = new MyEventSubscriber();
          $subscriber->onDomainEvent($event);
          $this->assertTrue(true); // Add assertions
      }
      
    • Mock RabbitMQ with VirtueMart/RabbitMQBundle or Enqueue:
      composer require enqueue/rabbitmq
      
  2. Extending the Bundle

    • Custom Event Types: Extend the DomainEvent class:
      namespace App\Event;
      
      use Ecentria\APIEventsBundle\Event\DomainEvent;
      
      class CustomEvent extends DomainEvent
      {
          public function getCustomData()
          {
              return $this->data['custom_field'] ?? null;
          }
      }
      
    • Dynamic Routing: Route events to different queues based on type:
      # config/packages/ecentria_api_events.yaml
      ecentria_api_events:
          routing:
              'user.*.': 'user_events_queue'
              'order.*.': 'order_events_queue'
      
  3. Monitoring

    • Track consumer health with Prometheus:
      use Prometheus\CollectorRegistry;
      
      class ConsumerMonitor
      {
          public function __invoke($message)
          {
              $registry->getCounter('api_events_processed')->inc();
          }
      }
      
    • Log unhandled exceptions:
      // In your consumer
      try {
          $this->processMessage($message);
      } catch (\Throwable $e) {
          error_log('Event processing failed: ' . $e->getMessage());
          $this->channel->basic_nack($deliveryInfo['delivery_tag'], false, true);
      }
      
  4. Security

    • Validate event payloads to prevent injection:
      use Symfony\Component\Validator\Validator\ValidatorInterface;
      
      class SecureEventSubscriber
      {
          public function __construct(private ValidatorInterface $validator) {}
      
          public function onDomainEvent(DomainEvent $event)
          {
              $errors = $this->validator->validate($event->getData());
              if (count($errors) > 0) {
                  throw new \RuntimeException('Invalid event data');
              }
          }
      }
      
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.
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
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