event-engine/php-document-store
DocumentStore interface fits perfectly as a port in Laravel’s layered architecture, enabling clean separation between domain logic and persistence. This complements Laravel’s repository pattern and service layer, reducing direct database access in business logic.replaceDoc/replaceMany methods prevent accidental merges, critical for consistency in event-sourced systems.PostgresDocumentStore in production, InMemoryDocumentStore in tests) with zero boilerplate.Schema::create/drop methods.Illuminate\Queue) for background processing.Illuminate\Database\Eloquent\Model).event-engine/postgres-document-store.DB facade).replace for local dev:
"repositories": [
{ "type": "path", "url": "../event-engine/persistence" }
],
"replace": {
"event-engine/persistence": "*"
}
persistence package as a volume.v0.8.2; no action required for Laravel 10+.| Risk | Impact | Mitigation |
|---|---|---|
| Schema Migrations | Manual index management needed. | Use Laravel’s migrations to create/drop indices (e.g., Schema::createIndex). |
| Transaction Support | No native Laravel transaction integration. | Wrap operations in DB::transaction() or use Laravel’s database transactions. |
| Query Complexity | Limited to contract methods. | Extend the interface or use Laravel Query Builder for advanced queries. |
| Performance Overhead | In-memory store not production-ready. | Benchmark against Laravel’s cache or database for critical paths. |
| BC Breaks | Minor (e.g., dropIndex args). |
Pin to v0.8.2 and use Laravel’s upgrade scripts for future changes. |
RefreshDatabase)?DocumentUpdated) or domain events (e.g., EventEngine\Event)?AppServiceProvider with environment-based implementations:
$this->app->bind(DocumentStore::class, function ($app) {
return config('app.env') === 'testing'
? new InMemoryDocumentStore()
: new PostgresDocumentStore($app['db']->connection());
});
document_store.enable_indexing).class User extends Model {
public function getDocumentAttribute() {
return $this->documentStore->findDoc($this->id);
}
}
User::observe(function ($model) {
$model->documentStore->replaceDoc($model->toArray());
});
replaceMany) to Laravel’s queues:
ReplaceManyDocuments::dispatch($collectionId, $docs)->onQueue('document-store');
Cache facade with tags for invalidation:
Cache::tags(['documents'])->remember("doc:{$id}", now()->addMinutes(5), fn() =>
$this->documentStore->findDoc($id)
);
app/Contracts/DocumentStore.php.config/document_store.php) for backend selection.PostgresDocumentStore with Laravel’s DB facade.EloquentDocumentStore) for ORM integration.class EloquentDocumentStore implements DocumentStore {
public function findDoc(string $id): ?array {
return Model::find($id)?->toArray();
}
// ... other methods
}
InMemoryDocumentStore in tests:
use function Pest\Laravel\actingAs;
actingAs()->withDocumentStore(InMemoryDocumentStore::class);
feature flags (e.g., spatie/laravel-feature-flags) to toggle implementations.| Laravel Component | Integration Notes |
|---|---|
| Eloquent | Requires manual sync between models and documents. Use observers or events. |
| Scout | Can index documents in Elasticsearch via a custom DocumentStore adapter. |
| Queues | Async operations should implement ShouldQueue (Laravel Jobs). |
| Notifications | Trigger notifications (e.g., DocumentUpdated) via Laravel’s Notification facade. |
| Horizon | Monitor queue jobs for document operations in Laravel’s Horizon dashboard. |
| Vapor | Deploy document store operations as serverless functions with minimal changes. |
DocumentStore calls.event-engine/php-document-store for BC breaks (e.g., dropIndex changes).upgrade command to handle schema migrations.How can I help you explore Laravel packages today?