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

Laravel Event Sourcing Laravel Package

spatie/laravel-event-sourcing

Event sourcing toolkit for Laravel: build aggregates, projectors, and reactors to store state changes as events. Ideal for audit trails, decisions based on history, and future reporting needs. Includes docs, examples, and an optional course.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Event-Driven Paradigm Alignment: Fits seamlessly into Laravel applications requiring event sourcing, CQRS, or audit trails. Ideal for domains where temporal queries, decision replay, or immutable state are critical (e.g., financial systems, compliance-heavy workflows).
  • Aggregate Pattern Support: Enables bounded contexts with encapsulated state transitions, reducing side effects in core logic.
  • Projection/Reactor Separation: Decouples read models (projections) from write operations, enabling scalable query performance and event-driven extensions.

Integration Feasibility

  • Laravel Native: Leverages Laravel’s service container, events, and queues natively, minimizing boilerplate.
  • Database Agnostic: Works with Eloquent (via spatie/laravel-event-sourcing-eloquent) or custom storage backends (e.g., PostgreSQL JSONB, Redis).
  • Event Store Flexibility: Supports SQL-based event stores (default) or external stores (e.g., EventStoreDB, Kafka) via custom adapters.

Technical Risk

  • Complexity Overhead: Event sourcing introduces new abstractions (aggregates, projections, reactors) that may require team upskilling and architectural discipline.
  • Performance Tradeoffs:
    • Write Path: Event appends are atomic but may impact throughput if not optimized (e.g., batching, async writes).
    • Read Path: Projections require materialization, adding latency for initial queries.
  • Debugging Challenges: Reconstructing state from events can complicate error tracing and local development (e.g., seeding test data).
  • Migration Risk: Existing CRUD-heavy applications may face refactoring costs to adopt aggregates.

Key Questions

  1. Domain Suitability:
    • Does the use case require temporal queries (e.g., "show me all states of this order") or auditability?
    • Is the team experienced with event-driven architectures (EDA)?
  2. Infrastructure Readiness:
    • Can the database handle event store growth (e.g., millions of events)?
    • Are eventual consistency and projection lag acceptable?
  3. Team Capacity:
    • Is there bandwidth to train developers on aggregates, projections, and reactors?
    • Can QA validate event replay and state reconstruction?
  4. Tooling/Gaps:
    • Are there monitoring tools for event store health (e.g., lag, duplicates)?
    • Does the team need GUI tools for event visualization (e.g., Spatie’s Event Sourcing Debugger)?

Integration Approach

Stack Fit

  • Laravel Ecosystem: Optimized for Laravel 9+/10+ with first-party integration (e.g., EventServiceProvider, Queue).
  • Database:
    • Primary: SQL (MySQL, PostgreSQL, SQLite) via Eloquent or raw queries.
    • Alternatives: Redis (for high-speed projections), EventStoreDB (for distributed systems).
  • Extensions:
    • spatie/laravel-event-sourcing-eloquent: Simplifies aggregate persistence.
    • spatie/laravel-event-sourcing-reactors: For side-effect handling (e.g., notifications).
    • spatie/laravel-event-sourcing-projections: For materialized views.

Migration Path

  1. Pilot Phase:
    • Start with a single aggregate (e.g., Order) to validate the pattern.
    • Use existing Eloquent models as a baseline, then refactor to aggregates.
  2. Incremental Adoption:
    • Write Path First: Replace CRUD updates with event emission (e.g., OrderUpdated).
    • Read Path Later: Introduce projections for queries (e.g., OrderProjection).
  3. Hybrid Approach:
    • Coexist with legacy models using reactors to bridge events to existing services.
    • Example: Emit UserRegistered event but keep users table for legacy APIs.

Compatibility

  • Laravel Versions: Tested on 9.x–10.x; may require adjustments for older versions.
  • PHP Versions: 8.1+ (type hints, attributes).
  • Dependencies:
    • Required: Laravel, Doctrine DBAL (for SQL storage).
    • Optional: Queue drivers (for async projections), Redis (for caching).
  • Conflict Risks:
    • Database Migrations: Event store tables (events, projections) must be managed carefully.
    • Event Naming: Avoid collisions with existing Laravel events (e.g., Illuminate\Events).

Sequencing

  1. Setup:
    • Install package: composer require spatie/laravel-event-sourcing.
    • Publish config: php artisan vendor:publish --provider="Spatie\EventSourcing\EventSourcingServiceProvider".
    • Configure event store (default: SQL).
  2. Aggregate Implementation:
    use Spatie\EventSourcing\AggregateRoot;
    
    class Order extends AggregateRoot
    {
        public function place(OrderPlaced $event)
        {
            $this->recordThat($event);
            // Business logic
        }
    }
    
  3. Projection Setup:
    use Spatie\EventSourcing\Projection;
    
    class OrderProjection extends Projection
    {
        public function whenOrderPlaced(OrderPlaced $event)
        {
            // Update materialized view
        }
    }
    
  4. Reactor Setup (Optional):
    use Spatie\EventSourcing\Reactor;
    
    class SendWelcomeEmailReactor extends Reactor
    {
        public function handle(OrderPlaced $event)
        {
            Mail::to($event->user)->send(new WelcomeEmail());
        }
    }
    
  5. Testing:
    • Use EventSourcing::fake() for unit tests.
    • Validate projections with Projection::refresh().

Operational Impact

Maintenance

  • Pros:
    • Auditability: Events serve as a single source of truth for debugging.
    • Backward Compatibility: Events enable time-travel debugging (replay past states).
  • Cons:
    • Projection Maintenance: Materialized views must be kept in sync with schema changes.
    • Event Schema Evolution: Breaking changes to events require migration strategies (e.g., versioned events).
  • Tooling Needs:
    • Event Store Monitoring: Track size, latency, and duplicate events.
    • Projection Health Checks: Alert on stale projections.

Support

  • Developer Onboarding:
    • Requires understanding of DDD concepts (aggregates, invariants).
    • Document event lifecycle (emission, projection, reaction).
  • Common Issues:
    • Event Loss: Queue failures or unhandled exceptions in reactors.
    • Projection Lag: Async projections may fall behind.
    • Concurrency: Optimistic locking needed for aggregates.
  • Debugging:
    • Use EventSourcing::getRecordedEvents() to inspect aggregate history.
    • Leverage Projection::refresh() to rebuild materialized views.

Scaling

  • Write Scaling:
    • Batch Events: Use Laravel queues to debounce event writes.
    • Sharding: Partition event store by aggregate type (e.g., orders_events, users_events).
  • Read Scaling:
    • Projection Caching: Cache materialized views (e.g., Redis).
    • Read Replicas: Offload projections to replicas.
  • Event Store Growth:
    • Archival: Move old events to cold storage (e.g., S3).
    • Compaction: Merge events into snapshots (requires custom logic).

Failure Modes

Failure Type Impact Mitigation
Event Store Corruption Lost events, inconsistent state. Backups, transactional writes.
Projection Failure Stale read models. Retry mechanisms, health checks.
Reactor Crash Missed side effects (e.g., emails). Dead-letter queues, exponential backoff.
Concurrency Issues Race conditions in aggregates. Optimistic locking, event versioning.
Database Downtime Unavailable event store. Multi-region replication, async fallback.

Ramp-Up

  • Training:
    • Workshops: Hands-on labs for aggregates/projections (e.g., Spatie’s Event Sourcing Course).
    • Pair Programming: Onboard senior devs first.
  • Documentation:
    • Architecture Decision Records (ADRs): Justify event sourcing choice.
    • Runbooks: Steps for common failures (e.g., "How to recover a stale projection").
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport