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

Domain Events Laravel Package

cvek/domain-events

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Domain-Driven Design (DDD) Alignment: The package aligns well with DDD principles by decoupling business logic from persistence concerns via domain events. This is particularly useful for Laravel applications adopting event-driven architectures (e.g., CQRS, event sourcing).
  • Symfony-Centric Design: While the package is Symfony-focused, its core concepts (domain events, Doctrine integration) are transferable to Laravel via custom adapters or middleware. Laravel’s event system (Illuminate\Events) can serve as a foundation for integration.
  • Separation of Concerns: The preFlush, onFlush, and postFlush categorization mirrors Laravel’s Model::saved(), Model::creating(), etc., but with finer-grained control over timing (e.g., async post-processing).

Integration Feasibility

  • Laravel Compatibility:
    • Doctrine ORM: If the application uses Doctrine (via laravel-doctrine), integration is straightforward. For Eloquent, a custom listener or event dispatcher would be needed.
    • Event System: Laravel’s built-in events can replace Symfony’s event dispatcher with minimal refactoring (e.g., Event::dispatch() instead of Symfony’s EventDispatcher).
    • Async Processing: Laravel’s queues (bus:listen, queue:work) can handle async events, but the package’s db transport would require a custom implementation (e.g., using Laravel’s jobs table or a message broker like Redis).
  • Entity Integration:
    • The RaiseEventsInterface/RaiseEventsTrait pattern can be replicated in Laravel using traits or interfaces (e.g., HasDomainEvents).
    • Example:
      trait HasDomainEvents {
          protected array $domainEvents = [];
          public function recordDomainEvent(object $event): void { ... }
      }
      

Technical Risk

  • Symfony Dependencies: The package relies on Symfony components (e.g., EventDispatcher, DoctrineBundle). Laravel alternatives exist but may require rewriting:
    • EventDispatcher: Replace with Laravel’s Illuminate\Events\Dispatcher.
    • Doctrine Events: Use Eloquent model observers or Laravel’s Model::observables().
  • Async Transport: The package’s db transport for async events is Doctrine-specific. Laravel would need a custom solution (e.g., database-backed queues or a message broker).
  • Testing Overhead: Migrating event logic may require updating tests, especially if the package’s event lifecycle differs from Laravel’s conventions.
  • Performance: Async events introduce complexity (e.g., retries, dead letters). Laravel’s queue system mitigates this but adds operational overhead.

Key Questions

  1. ORM Strategy:
    • Is the application using Eloquent or Doctrine? If Eloquent, how will onFlush/postFlush timing be replicated?
    • Are there plans to adopt Doctrine, or is this a one-time integration?
  2. Async Requirements:
    • What async workloads are needed (e.g., notifications, external APIs)? Can Laravel’s queues handle them, or is a custom transport required?
  3. Event Granularity:
    • Should events be coarse-grained (e.g., "OrderCreated") or fine-grained (e.g., "OrderItemAdded")? This affects entity integration complexity.
  4. Existing Event System:
    • Does the application already use Laravel’s events? If so, how will this package’s events coexist or replace them?
  5. Database Schema:
    • The package stores async events in a database table. Will this conflict with Laravel’s migrations or require a custom schema?
  6. Error Handling:
    • How will failed async events be retried or logged? Laravel’s queue failures need alignment with the package’s expectations.

Integration Approach

Stack Fit

  • Laravel Core:
    • Replace Symfony’s EventDispatcher with Laravel’s Illuminate\Events\Dispatcher.
    • Use Laravel’s model observers or accessors/mutators to trigger preFlush/onFlush events.
    • Leverage Eloquent events (creating, updating, saved) for postFlush logic.
  • Async Processing:
    • Replace the package’s db transport with Laravel’s queue system (e.g., bus:listen for async events).
    • Store pending events in jobs table or a custom table (e.g., domain_events).
    • Use Laravel Horizon or Supervisor to manage workers.
  • Doctrine vs. Eloquent:
    • Doctrine: Use the package as-is with minimal adapters (e.g., wrap Symfony events in Laravel listeners).
    • Eloquent: Build a custom trait/class to mimic the package’s behavior (e.g., HasDomainEvents trait dispatching Laravel events).

Migration Path

  1. Phase 1: Proof of Concept

    • Implement a minimal HasDomainEvents trait in Laravel to test event raising/dispatching.
    • Example:
      trait HasDomainEvents {
          protected array $domainEvents = [];
          public function recordDomainEvent(object $event): void {
              $this->domainEvents[] = $event;
          }
          protected static function booted(): void {
              static::saved(function ($model) {
                  foreach ($model->domainEvents as $event) {
                      event($event);
                  }
              });
          }
      }
      
    • Verify preFlush/postFlush timing using Eloquent observers.
  2. Phase 2: Async Integration

    • Create a custom async transport using Laravel queues:
      • Store events in domain_events table with status (pending/processed).
      • Dispatch a HandleDomainEvent job for async events.
      • Use queue:listen to process events.
    • Example job:
      class HandleDomainEvent implements ShouldQueue {
          public function handle(DomainEvent $event) {
              // Process async logic (e.g., send email, call API)
          }
      }
      
  3. Phase 3: Full Feature Parity

    • Replace Symfony-specific components (e.g., AbstractSyncDomainEvent) with Laravel-compatible abstractions.
    • Add support for onFlush events using Eloquent’s updating observer.
    • Example onFlush handler:
      Model::observe(function ($model) {
          if (method_exists($model, 'getDomainEvents')) {
              foreach ($model->getDomainEvents() as $event) {
                  if ($event instanceof OnFlushDomainEvent) {
                      // Process sync logic during "update"
                  }
              }
          }
      });
      
  4. Phase 4: Testing and Optimization

    • Write Pest/PHPUnit tests for event lifecycle (sync/async).
    • Benchmark performance (e.g., async event processing latency).
    • Optimize database queries (e.g., batch event processing).

Compatibility

  • Laravel 10/11: Fully compatible with minor adjustments (e.g., event dispatching syntax).
  • Doctrine Bridge: If using laravel-doctrine, the package can be integrated with ~80% reuse. Eloquent requires custom logic.
  • Third-Party Packages:
    • Laravel Echo/Pusher: Can integrate with async events for real-time notifications.
    • Spatie Laravel Activitylog: May conflict with domain events; evaluate duplication of concerns.

Sequencing

Step Dependency Owner
1. Define Event Types Business logic analysis Backend Team
2. Implement Trait Laravel event system TPM/Backend Lead
3. Async Transport Queue worker setup DevOps/Backend
4. Doctrine/Eloquent Adapter ORM-specific logic Backend Team
5. Testing Test suite QA/Backend
6. Rollout Feature flag or phased release Product/Engineering

Operational Impact

Maintenance

  • Pros:
    • Decoupled Logic: Domain events isolate business logic from persistence, reducing side effects.
    • Laravel Native: Using Laravel’s events/queues aligns with the ecosystem (e.g., easier debugging with telescope).
  • Cons:
    • Custom Async Transport: Requires maintaining a queue worker and database table for async events.
    • Event Schema: Additional table(s) for async events may need migrations/backups.
    • Symfony Legacy: If the package is updated, Laravel-specific forks may diverge.

Support

  • Debugging:
    • Sync Events: Leverage Laravel’s EventServiceProvider and telescope for tracking.
    • Async Events: Use queue:failed and telescope to monitor failed jobs.
    • Doctrine Events: If using Doctrine, Symfony’s event docs may still apply; document Laravel-specific quirks.
  • Common Issues:
    • Event Ordering: Async events may not guarantee order; document expectations.
    • Duplicate Events: Idempotency checks needed for async retries.
    • Performance: Async events add latency; monitor queue backlogs.

Scaling

  • Horizontal Scaling:
    • **
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.
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
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