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

Outbox Bundle Laravel Package

agluh/outbox-bundle

Laravel outbox pattern bundle for reliable event publishing: capture domain events in an outbox table within your transaction, then dispatch them asynchronously to queues or brokers. Helps avoid dual-write issues and improves consistency between your DB and integrations.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Outbox Pattern Alignment: The package implements the Outbox pattern, a critical component for event-driven architectures (EDA) and DDD-based Symfony apps. It ensures reliable event publishing by decoupling event generation from processing via a transactional outbox table.
  • Symfony/DDD Focus: Tailored for Symfony + Doctrine ORM, making it a natural fit for applications already using these stacks. Leverages Symfony Lock for concurrency control and Ramsey UUID for event IDs, aligning with modern DDD practices.
  • Limitation: Laravel-specific adaptations may be needed (e.g., Symfony’s EventDispatcher vs. Laravel’s Events facade, Doctrine vs. Eloquent, Symfony Lock vs. Laravel’s mutex alternatives).

Integration Feasibility

  • Core Components:
    • Outbox Table: Requires a outbox_message table (Doctrine schema). Laravel’s migrations can adapt this.
    • Event Dispatcher: Symfony’s EventDispatcher must be replaced with Laravel’s Events or a custom bridge (e.g., symfony/event-dispatcher via Composer).
    • Message Processing: Uses Symfony’s Console commands for polling. Laravel’s queues (e.g., php artisan queue:work) or scheduler can replace this.
  • Key Dependencies:
    • Doctrine ORM: Laravel uses Eloquent by default. A hybrid approach (Doctrine for outbox, Eloquent for domain) or full Doctrine migration may be needed.
    • Symfony Lock: Replace with Laravel’s Illuminate\Support\Facades\Lock or a package like spatie/laravel-lock.

Technical Risk

  • High:
    • Symfony ↔ Laravel Abstraction Layer: Requires wrapper classes for Symfony-specific components (e.g., EventDispatcher, Lock).
    • Doctrine vs. Eloquent: Schema changes and repository patterns may conflict with Laravel conventions.
    • Event Publishing: Symfony’s EventDispatcher emits events differently than Laravel’s Events::dispatch(). A custom event listener bridge is needed.
  • Medium:
    • UUID Handling: ramsey/uuid-doctrine must be adapted for Eloquent or replaced with Laravel’s webpatser/uuid.
    • Testing: Symfony’s test bundles (e.g., matthiasnoback/symfony-dependency-injection-test) are incompatible; Laravel’s Pest/PHPUnit will require custom fixtures.
  • Low:
    • MIT License: No legal barriers.
    • PHP 7.4+ Compatibility: Aligns with Laravel 8+/9+.

Key Questions

  1. Event-Driven Workflow:
    • How will Laravel’s Events/Listeners integrate with the Outbox’s Symfony-style event dispatching?
    • Will we use the Outbox for all events or only critical domain events?
  2. Database Layer:
    • Should we migrate to Doctrine ORM for consistency, or use Eloquent with a custom Outbox repository?
    • How will the outbox_message table schema translate to Laravel migrations?
  3. Message Processing:
    • Will we replace Symfony’s Console commands with Laravel queues (e.g., busy queue) or a custom scheduler job?
    • How will we handle retries and dead-letter queues (DLQ)?
  4. Concurrency Control:
    • What’s the fallback if Symfony Lock isn’t directly replaceable? (e.g., database SELECT ... FOR UPDATE or spatie/laravel-lock).
  5. Testing Strategy:
    • How will we mock the Outbox in Laravel’s testing environment (e.g., Pest/PHPUnit)?
    • Are there plans to contribute Laravel-specific test utilities upstream?

Integration Approach

Stack Fit

  • Laravel Compatibility:
    • Partial Fit: The package is Symfony-first, but Laravel can adopt its core Outbox pattern with adaptations.
    • Key Mappings:
      Symfony Component Laravel Equivalent Adaptation Strategy
      EventDispatcher Events facade Custom bridge class (e.g., SymfonyEventDispatcher)
      Doctrine ORM Eloquent Hybrid: Use Doctrine for outbox only, or migrate fully
      Symfony Lock spatie/laravel-lock Replace with Lock facade or DB locks
      Console commands Artisan commands / Queues Convert to Laravel jobs or scheduled tasks
  • Non-Negotiables:
    • Outbox Table Schema: Must be implemented (Laravel migration).
    • Transactional Writes: Ensure event insertion and domain transaction are atomic (Laravel’s DB transactions suffice).

Migration Path

  1. Phase 1: Proof of Concept (PoC)

    • Goal: Validate Outbox pattern feasibility in Laravel.
    • Steps:
      • Create the outbox_message table via Laravel migration.
      • Implement a minimal Outbox service (without Symfony dependencies).
      • Test with a single event type (e.g., OrderCreated).
    • Deliverable: Basic event → outbox → queue flow.
  2. Phase 2: Symfony Dependency Replacement

    • Goal: Replace Symfony-specific components.
    • Steps:
      • Replace EventDispatcher with a Laravel-compatible bridge.
      • Replace Symfony Lock with spatie/laravel-lock or DB locks.
      • Adapt Doctrine entities to Eloquent models (or vice versa).
    • Deliverable: Functional Outbox with Laravel-native components.
  3. Phase 3: Full Integration

    • Goal: Seamless event-driven workflow.
    • Steps:
      • Integrate with Laravel’s queue system for message processing.
      • Add retries, DLQ, and monitoring (e.g., Laravel Horizon).
      • Write comprehensive tests (unit + integration).
    • Deliverable: Production-ready Outbox pattern in Laravel.

Compatibility

  • Doctrine vs. Eloquent:
    • Option A (Recommended): Use Eloquent for the outbox to avoid Doctrine overhead.
      • Pros: Leverages Laravel’s ORM, simpler migration.
      • Cons: Loses some Doctrine features (e.g., lifecycle callbacks).
    • Option B: Migrate entire app to Doctrine.
      • Pros: Full compatibility with the bundle.
      • Cons: Significant refactoring, may conflict with Laravel conventions.
  • Event System:
    • Symfony Events → Laravel Events:
      • Create a wrapper class to translate Symfony events to Laravel’s Events::dispatch().
      • Example:
        class SymfonyEventDispatcherBridge {
            public function dispatch(object $event) {
                Events::dispatch($event);
            }
        }
        
  • Message Processing:
    • Replace Symfony’s Console commands with Laravel jobs (e.g., ProcessOutboxMessages).
    • Use Laravel queues (database, redis, etc.) for polling.

Sequencing

  1. Database Schema:
    • Create outbox_message table (adapted from Symfony’s schema).
    • Example migration:
      Schema::create('outbox_message', function (Blueprint $table) {
          $table->id();
          $table->uuid('message_id');
          $table->string('type');
          $table->json('payload');
          $table->timestamp('occurred_at')->useCurrent();
          $table->boolean('processed')->default(false);
          $table->timestamps();
      });
      
  2. Outbox Service:
    • Implement Outbox class to handle store() and getUnprocessed().
  3. Event Listeners:
    • Hook into domain events (e.g., OrderCreated) to publish to the outbox.
  4. Message Processor:
    • Create a Laravel job to poll and process outbox messages.
  5. Testing:
    • Write unit tests for the Outbox service.
    • Test end-to-end flow (event → outbox → queue → consumer).

Operational Impact

Maintenance

  • Pros:
    • Decoupled Event Publishing: Outbox pattern reduces coupling between services.
    • Audit Trail: Outbox table serves as a reliable event log for debugging.
    • Backpressure Handling: Failed events can be retried or routed to a DLQ.
  • Cons:
    • Additional Table: Requires monitoring of outbox_message growth.
    • Complexity: More moving parts (outbox + queue + consumers) increase operational overhead.
  • Mitigations:
    • Automated Cleanup: Schedule a job to purge old processed messages.
    • Monitoring: Track processed_at delays and failure rates (e.g., with Laravel Scout or Prometheus).

Support

  • Debugging:
    • Event Visibility: Outbox table provides a
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.
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
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