CQRS, Event Sourcing, Workflows, and Production Resilience for Laravel and Symfony
Install with Composer · Configure with PHP Attributes · Works with your existing codebase
Laravel handles HTTP beautifully. But the moment you need event sourcing, sagas, or multi-step workflows — you're stitching packages together. Ecotone gives you one coherent toolkit: aggregates, projections, outbox, and more — all attribute-driven, all testable in-process, all running on the Laravel queues you already have.
Every mature platform has this. Now PHP does too.
| Ecosystem | Framework | Enterprise Patterns | CQRS | Event Sourcing | Workflows | Messaging |
|---|---|---|---|---|---|---|
| Java | Spring | Axon Framework | ||||
| .NET | ASP.NET | NServiceBus / MassTransit | ||||
| PHP | Laravel / Symfony | Ecotone |
Enterprise patterns, zero boilerplate — just PHP attributes
Separate command and query models. Decouple business logic from infrastructure with clean PHP attributes.
Store events, not state. Build read models from event streams. Full audit trail with time travel and replay.
Orchestrate multi-step business processes. Handle long-running operations and compensation logic declaratively.
RabbitMQ, Kafka, SQS, DBAL. Distributed bus across services. Move sync to async with one attribute.
Automatic retries, dead letter queues, deduplication, failure isolation. Your system self-heals.
Aggregates, domain events, bounded contexts. Pure PHP objects with no framework coupling in your domain.
// Asynchronous command handler — that's the entire setup
#[Asynchronous('orders')]
#[CommandHandler]
public function placeOrder(PlaceOrder $command): void
{
$order = Order::create($command->orderId, $command->items);
$this->orderRepository->save($order);
}
// Ecotone handles the rest:
// ✓ Async execution via RabbitMQ / Kafka / SQS / DBAL
// ✓ Automatic retries on failure
// ✓ Dead letter queue if all retries fail
// ✓ Message tracing and correlationYour tests run through the same messaging pipeline as production — bus routing, async channels, event propagation — all in one process. Send a message, run the flow, assert the result. The test shape never changes.
Extract exactly the flow you care about and test it in isolation:
// Test a specific flow in isolation — only the services you need
$ecotone = EcotoneLite::bootstrapFlowTesting([OrderService::class]);
$ecotone->sendCommand(new PlaceOrder('order-1'));
$this->assertEquals('placed', $ecotone->sendQueryWithRouting('order.getStatus', 'order-1'));Bring in async handlers, enable an in-memory channel, and verify the full flow:
// Test the full async flow — in-memory channel, same process
$notifier = new InMemoryNotificationSender();
$ecotone = EcotoneLite::bootstrapFlowTesting(
[OrderService::class, NotificationService::class],
[NotificationSender::class => $notifier],
enableAsynchronousProcessing: [
SimpleMessageChannelBuilder::createQueueChannel('notifications')
]
);
$ecotone
->sendCommand(new PlaceOrder('order-1'))
->run('notifications');
$this->assertEquals(['order-1'], $notifier->getSentOrderConfirmations());Swap the in-memory channel for DBAL, RabbitMQ, or Kafka in production — the test stays the same. Ecotone runs the consumer in-process, so switching transports never changes how you test.
Declarative configuration that any coding agent can follow and reproduce. Testing support that lets it verify even the most advanced flows. Less guessing, no hallucinating — just confident iteration.
Declarative attributes mean less infrastructure code to feed into the AI's context window and less boilerplate to generate. Smaller input and output means lower cost, faster iteration and more accurate results.
Ready-to-use skills that teach any coding agent how to correctly write handlers, aggregates, sagas, projections, and tests. Your AI generates idiomatic Ecotone code from the start.
Direct documentation access for AI assistants via Model Context Protocol. Works with Claude Code, Cursor, Windsurf, GitHub Copilot, and others.
The same straightforward test model applies to async flows. Your coding agent writes tests that run the real pipeline — no special setup to guess at.
Add Ecotone to your existing Laravel or Symfony project in minutes.
composer require ecotone/laravel