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

Php Persistence Laravel Package

event-engine/php-persistence

Event Engine PHP Persistence Package providing persistence layer utilities for PHP-based event-sourced and CQRS applications. Supports storing and retrieving events and state in a consistent way to integrate with Event Engine workflows.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**
   ```bash
   composer require event-engine/php-persistence:^0.9.2

Register the service provider in config/app.php:

'providers' => [
    // ...
    EventEngine\Persistence\PersistenceServiceProvider::class,
],
  1. Basic Configuration Publish the config file:

    php artisan vendor:publish --provider="EventEngine\Persistence\PersistenceServiceProvider" --tag="config"
    

    Update config/persistence.php with your storage backend (e.g., database, redis, or filesystem). Note: This package now fully supports PHP 8.0+ and has removed all PHP 8.4 deprecation warnings, making it compatible with modern PHP versions.

  2. First Use Case: Persisting an Event

    use EventEngine\Persistence\Persistence;
    
    $persistence = app(Persistence::class);
    $event = new YourEventClass(['data' => 'payload']);
    
    // Persist with default strategy
    $persistence->persist($event);
    
    // Retrieve later
    $storedEvent = $persistence->retrieve($event->getId());
    

Implementation Patterns

Core Workflows

  1. Event Persistence Strategies

    • Default Strategy: Uses the configured backend (e.g., database).
      $persistence->persist($event, ['strategy' => 'database']);
      
    • Custom Strategies: Extend EventEngine\Persistence\Strategies\StrategyInterface and bind in config/persistence.php:
      'strategies' => [
          'custom' => \App\Strategies\CustomPersistenceStrategy::class,
      ],
      
  2. Event Retrieval

    • Fetch by ID:
      $event = $persistence->retrieve('event-uuid-here');
      
    • Query events with filters (if supported by backend):
      $events = $persistence->query([
          'type' => YourEventClass::class,
          'after' => now()->subHours(1),
      ]);
      
  3. Event Sourcing Pattern

    • Load a stream of events for an aggregate:
      $stream = $persistence->loadStream('aggregate-id', YourEventClass::class);
      foreach ($stream as $event) {
          // Replay event
      }
      
  4. Middleware Integration

    • Attach middleware to persistence operations:
      $persistence->persist($event)->withMiddleware([
          \EventEngine\Persistence\Middleware\LogMiddleware::class,
          \EventEngine\Persistence\Middleware\ValidateMiddleware::class,
      ]);
      

Integration Tips

  1. Database Backend

    • Ensure your events table has columns: id, type, payload, occurred_at, metadata.
    • Use migrations or schema builder to define the table:
      Schema::create('events', function (Blueprint $table) {
          $table->id();
          $table->string('type');
          $table->json('payload');
          $table->timestamp('occurred_at')->useCurrent();
          $table->json('metadata')->nullable();
      });
      
  2. Redis Backend

    • Configure in config/persistence.php:
      'backends' => [
          'redis' => [
              'driver' => 'redis',
              'connection' => 'cache',
          ],
      ],
      
    • Useful for high-throughput scenarios with TTL-based event expiration.
  3. Filesystem Backend

    • Store events as JSON files in a directory (e.g., storage/app/persistence).
    • Ideal for local development or offline systems.
  4. Event Metadata

    • Attach metadata during persistence:
      $persistence->persist($event, [
          'metadata' => ['user_id' => 123, 'source' => 'api'],
      ]);
      
  5. Testing

    • Use the PersistenceTestCase trait or mock the Persistence facade:
      $this->mock(Persistence::class)->shouldReceive('persist')->once();
      

Gotchas and Tips

Pitfalls

  1. Payload Serialization

    • Ensure your event payload is JSON-serializable. Non-serializable objects (e.g., closures, resources) will fail.
    • Fix: Implement JsonSerializable or use json_encode($payload, JSON_THROW_ON_ERROR).
    • PHP 8.0+ Note: JSON serialization is now stricter. Test edge cases like null values or complex objects.
      • PHP 8.4+: If upgrading later, ensure compatibility with new JSON features (e.g., JSON_THROW_ON_ERROR).
  2. ID Collisions

    • If generating IDs manually (e.g., Str::uuid()), ensure uniqueness across backends.
    • Tip: Use Laravel’s Str::orderedUuid() for globally unique IDs.
  3. Transaction Boundaries

    • Database backend does not automatically wrap persistence in transactions. Handle manually:
      DB::transaction(function () use ($persistence, $event) {
          $persistence->persist($event);
          // Other DB operations...
      });
      
  4. Backend-Specific Quirks

    • Database: Index type and occurred_at for query performance.
    • Redis: Keys may expire if TTL is set. Monitor with redis-cli --scan.
    • Filesystem: Race conditions possible when writing multiple events. Use Storage::lock().
  5. Event Type Registration

    • If using polymorphic queries, ensure event classes are registered in the config:
      'event_types' => [
          \App\Events\UserCreated::class,
          \App\Events\OrderPlaced::class,
      ],
      

Debugging

  1. Enable Logging Add to config/persistence.php:

    'debug' => env('PERSISTENCE_DEBUG', false),
    

    Logs will appear in storage/logs/laravel.log.

  2. Query Inspection For database backend, enable query logging:

    DB::enableQueryLog();
    $persistence->query([...]);
    dd(DB::getQueryLog());
    
  3. Common Errors

    • "Class not found": Verify the event class is autoloaded or manually registered.
    • "Invalid payload": Check for circular references in JSON serialization. PHP 8.0+: Use JsonSerializable or #[AllowDynamicProperties] if needed.
    • "Backend not configured": Confirm config/persistence.php has valid backend settings.

Extension Points

  1. Custom Backends Implement EventEngine\Persistence\Backends\BackendInterface:

    class S3Backend implements BackendInterface {
        public function persist(Event $event, array $options) { ... }
        public function retrieve(string $id) { ... }
        // ...
    }
    

    Bind in config/persistence.php:

    'backends' => [
        's3' => \App\Backends\S3Backend::class,
    ],
    
  2. Event Transformers Modify payloads before/after persistence:

    $persistence->persist($event)->withTransformer(
        \App\Transformers\EncryptPayloadTransformer::class
    );
    
  3. Hooks Subscribe to persistence events via Laravel’s events facade:

    Event::listen(\EventEngine\Persistence\Events\EventPersisted::class, function ($event) {
        // Post-persistence logic
    });
    
  4. Batch Operations For bulk persistence, use the batch method:

    $persistence->batch($events)->persist();
    

    Supports custom batch sizes and error handling.


PHP 8.0+ Specifics

  1. Type Safety Leverage PHP 8.0+ features like union types or attributes for event classes:

    #[Attribute]
    class EventAttribute { ... }
    
    #[EventAttribute]
    class UserCreated { ... }
    
  2. Named Arguments Use named arguments for clarity in persistence options:

    $persistence->persist($event, strategy: 'database', metadata: ['user_id' => 123]);
    
  3. Constructor Property Promotion Simplify event class definitions:

    class UserCreated {
        public function __construct(
            public string $userId,
            public string $name,
        ) {}
    }
    
  4. PHP 8.4+ Compatibility

    • The package now explicitly removes PHP 8.4 deprecation warnings, ensuring smooth upgrades.
    • If using PHP 8.4+, test with JSON_THROW_ON_ERROR for stricter JSON validation.
  5. Modern PHP Features

    • Readonly Properties: Use in event classes for immutability:
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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor