- How does Verbs differ from traditional Laravel Eloquent models for event sourcing?
- Verbs replaces Eloquent models with State classes that track changes via events (verbs) instead of direct database updates. For example, instead of updating a `Customer` model directly, you emit `CustomerBeganTrial` events, which Verbs replays to reconstruct state. This ensures auditability and replayability without manual event logging.
- Can I use Verbs incrementally in an existing Laravel app, or is it an all-or-nothing approach?
- Verbs supports incremental adoption. Start by wrapping critical workflows (e.g., payments, subscriptions) in State classes and events, while leaving simpler CRUD operations untouched. The package integrates with Laravel’s service container, so you can mix Verbs and Eloquent models in the same app.
- What Laravel versions and PHP requirements does Verbs support?
- Verbs requires **Laravel 10+** and **PHP 8.1+** to leverage modern features like attributes and enums. It’s designed for Laravel’s latest ecosystem (e.g., Livewire, middleware integration) and avoids backward-compatibility pitfalls. Check the [docs](https://verbs.thunk.dev/) for minor version notes.
- How do I handle metadata (e.g., user_id, team_id) in events without repeating it in every event?
- Use `Verbs::createMetadataUsing()` to dynamically attach metadata (e.g., from Laravel’s middleware like `auth()->user()->team_id`) to every event. This avoids duplication and keeps events clean. Metadata is stored alongside events in the database and replayed automatically during state reconstruction.
- Does Verbs work with PostgreSQL, or is it MySQL-only?
- Verbs is database-agnostic and works with **PostgreSQL, MySQL, and other databases supported by Laravel’s query builder**. The event store schema is abstracted, so you can switch databases without changing application logic. Just ensure your database supports JSON fields for event storage.
- How do I test event-sourced state transitions in PHPUnit?
- Test state transitions by replaying event streams in isolation. Use `Verbs::replay()` to load a state from its event history, then assert the final state. For example: `$state = Verbs::replay(CustomerState::class, $eventStream); $this->assertEquals('active', $state->status)`. Mock event streams for edge cases like concurrent updates.
- What’s the performance impact of storing every event vs. snapshots?
- Storing every event enables full replayability but increases storage and replay time. Mitigate this with **snapshots**: call `Verbs::snapshot()` periodically to save state to the database. Snapshots reduce replay time for large event streams while retaining auditability. Balance this against your app’s read-heavy vs. write-heavy workload.
- Can Verbs handle nested or child states (e.g., a `Subscription` state within a `Customer` state)?
- Yes, use the `#[AppliesToChildState]` attribute to define child states. For example, a `Customer` state might have a `Subscription` child state that emits events like `SubscriptionRenewed`. Verbs ensures consistency by replaying events in the correct order. Document your state hierarchy clearly to avoid ambiguity in event application.
- Are there alternatives to Verbs for event sourcing in Laravel?
- Alternatives include **Laravel Event Sourcing** (basic event logging), **ProophEventStore** (more low-level), or **Axon Framework** (Java/PHP port). Verbs stands out by focusing on **developer experience**—minimal boilerplate, Laravel-native integration, and a State-first approach. Choose Verbs if you want a balance of simplicity and power for PHP artisans.
- How do I debug issues when state reconstruction fails during event replay?
- Enable verbose logging with `Verbs::setDebug(true)` to see event replay steps. Use `Verbs::getEventStream()` to inspect the raw event history for a state. For complex failures, replay events manually in a test to isolate the problematic event. Tools like Laravel Telescope can help trace middleware or metadata issues affecting event application.