spatie/laravel-event-sourcing
Event sourcing toolkit for Laravel: build aggregates, projectors, and reactors to store state changes as events. Ideal for audit trails, decisions based on history, and future reporting needs. Includes docs, examples, and an optional course.
Now that you've written your first projector, let's learn how to handle side effects. With side effects we mean things like sending a mail, sending a notification, ... You only want to perform these actions when the original event happens. You don't want to do this work when replaying events.
A reactor is a class, that much like a projector, listens for incoming events. Unlike projectors however, reactors will not get called when events are replayed. Reactors only will get called when the original event fires.
Reactors that perform some kind of API calls, think sending a mail or a notification, will be slow. We highly recommend that all reactors implement Illuminate\Contracts\Queue\ShouldQueue. Letting your reactor implement this marker interface will make the package start a queue job. The reactor will be called when that queued job is handled.
Let's create your first reactor. You can perform php artisan make:reactor BigAmountAddedReactor to create a reactor in app\Reactors. We will make this reactor send a mail to the director of the bank whenever a big amount of money is added to an account. Typehinting MoneyAdded will make our package call onMoneyAdded when the event occurs.
namespace App\Reactors;
use App\Account;
use App\Events\MoneyAdded;
use App\Mail\BigAmountAddedMail;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Mail;
use Spatie\EventSourcing\EventHandlers\Reactors\Reactor;
class BigAmountAddedReactor extends Reactor implements ShouldQueue
{
public function onMoneyAdded(MoneyAdded $event)
{
if ($event->amount < 900) {
return;
}
$account = Account::uuid($event->accountUuid);
Mail::to('director@bank.com')->send(new BigAmountAddedMail($account, $event->amount));
}
}
By default, the package will automatically find and use your reactor.
The reactor above will send an email to the director of the bank whenever an amount of 900 or more gets added to an account. Let's put the reactor to work.
$account = Account::createWithAttributes(['name' => 'Rey']);
$account->addMoney(1000);
A mail will be sent to the director.
If you truncate the accounts table and rebuild the contents with
php artisan event-sourcing:replay
no mail will be sent.
Reactors and process managers (which are built on top of the core reactor principle) are thoroughly discussed in Event Sourcing in Laravel. More specifically, you want to read these chapters:
How can I help you explore Laravel packages today?