- How do I integrate this message repository into an existing Laravel app using EventSauce?
- First, install the package and EventSauce core via Composer. Then, configure the repository using Laravel’s DBAL connection (e.g., `app('db')->getDoctrineConnection()`) and pass it to `DoctrineUuidV4MessageRepository`. Replace direct event storage with `$repository->store($event)`. Ensure your app uses EventSauce’s UUID generation, not Laravel’s `Str::uuid()`.
- Does this work with Laravel’s built-in event system or only EventSauce?
- This package is **only for EventSauce**—it replaces Laravel’s default event system with event-sourcing. If you’re using Laravel’s events table or Redis, you’ll need to migrate data to this repository’s schema (e.g., `event_id`, `aggregate_root_id`, `payload`). EventSauce provides serialization and UUID handling, so avoid mixing systems.
- What Laravel versions support this package, and does it require full Doctrine ORM?
- This package works with **Laravel 8+** and uses **Doctrine DBAL 3** (included in Laravel), so no full Doctrine ORM is needed. It leverages Laravel’s `db()` helper to access the DBAL connection, making setup minimal. Tested with Laravel’s latest stable releases, but check the [EventSauce compatibility matrix](https://github.com/EventSaucePHP/EventSauce) for core library support.
- Can I use binary UUIDs in MySQL, or should I stick to string UUIDs?
- Binary UUIDs (default) work in MySQL but require storing them as `BINARY(16)` or `VARBINARY(16)`. String UUIDs (via `UuidStringEncoder`) are simpler for databases without UUID extensions. Binary UUIDs save space and avoid string parsing but may complicate queries. Test your DB’s UUID handling first—PostgreSQL natively supports UUID types, while MySQL requires extensions or binary storage.
- How do I add custom columns (e.g., for indexing) to the event table?
- Extend `TableSchema` and override `additionalColumns()`. For example, add `created_at` or `metadata` columns by returning a `Header` array. Then pass your custom schema to the repository constructor. This is useful for indexing events by type, timestamp, or tenant ID without bloating the payload. See the [README’s custom schema section](https://github.com/EventSaucePHP/MessageRepositoryForDoctrine#custom-implementations).
- Will this handle concurrent event writes safely (e.g., race conditions)?
- The repository uses **optimistic locking via the `version` column**—each aggregate root has a version number that increments on writes. If two processes try to write to the same aggregate at the same version, the second will fail (returning a `ConcurrentModificationException`). For high-contention scenarios, consider adding a `retry` mechanism or database-level locks (e.g., `SELECT ... FOR UPDATE`).
- Can I query events by type, aggregate ID, or date range?
- Yes, but you’ll need to design your schema for it. The default schema includes `event_type` (in `LegacyTableSchema`) and `version`, while custom schemas can add `created_at` or `metadata` columns. For example, add `event_type` as an indexable column to filter events by type. Querying requires raw DBAL queries (e.g., `WHERE aggregate_root_id = ? AND event_type = ?`), as this isn’t an ORM.
- What’s the migration path if I’m currently using Laravel’s events table?
- Export events from Laravel’s `events` table (or your custom table) into the new schema. Use a data migration to map `id` → `event_id`, `payload` → `payload`, and add `aggregate_root_id`/`version`. For aggregates, track versions manually or replay events to rebuild state. Test projections/audits thoroughly—event-sourcing requires exact replayability. The `LegacyTableSchema` may help align columns.
- Are there performance benchmarks or known bottlenecks?
- No official benchmarks exist, but this package is optimized for **write-heavy workloads** (event-sourcing). Binary UUIDs reduce storage overhead, and DBAL queries are lightweight. Potential bottlenecks include: (1) Large payloads (compress JSON if needed), (2) High concurrency (use `version` locking), and (3) Complex queries (index custom columns). For read-heavy apps, consider a read model (CQRS) alongside this store.
- What alternatives exist for event storage in Laravel?
- If avoiding EventSauce, use Laravel’s built-in `events` table (simple but not event-sourcing), **ProophEventStore** (another PHP ES library with Doctrine support), or **Redis** (for ephemeral events). For SQL-based stores, **Laravel Event Store** (community packages) or raw DBAL tables work. EventSauce’s strength is **strict event versioning and replayability**, so alternatives may lack these guarantees.