Usage with Laravel-data? #477
-
Does this package work well when paired with the laravel-data package? I haven't done a ton of testing yet, but already seeing some possible roadblocks while testing, like:
|
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 6 replies
-
See #450 (comment) for our preferred way of using stored events with Laravel Data. |
Beta Was this translation helpful? Give feedback.
-
Example with current Laravel data: Base event use Illuminate\Contracts\Support\Responsable;
use Spatie\EventSourcing\StoredEvents\ShouldBeStored;
use Spatie\LaravelData\Concerns\AppendableData;
use Spatie\LaravelData\Concerns\BaseData;
use Spatie\LaravelData\Concerns\ContextableData;
use Spatie\LaravelData\Concerns\EmptyData;
use Spatie\LaravelData\Concerns\IncludeableData;
use Spatie\LaravelData\Concerns\ResponsableData;
use Spatie\LaravelData\Concerns\TransformableData;
use Spatie\LaravelData\Concerns\ValidateableData;
use Spatie\LaravelData\Concerns\WrappableData;
use Spatie\LaravelData\Contracts\AppendableData as AppendableDataContract;
use Spatie\LaravelData\Contracts\BaseData as BaseDataContract;
use Spatie\LaravelData\Contracts\EmptyData as EmptyDataContract;
use Spatie\LaravelData\Contracts\IncludeableData as IncludeableDataContract;
use Spatie\LaravelData\Contracts\ResponsableData as ResponsableDataContract;
use Spatie\LaravelData\Contracts\TransformableData as TransformableDataContract;
use Spatie\LaravelData\Contracts\ValidateableData as ValidateableDataContract;
use Spatie\LaravelData\Contracts\WrappableData as WrappableDataContract;
abstract class EventWithData extends ShouldBeStored implements AppendableDataContract, BaseDataContract, EmptyDataContract, IncludeableDataContract, Responsable, ResponsableDataContract, TransformableDataContract, ValidateableDataContract, WrappableDataContract
{
use AppendableData;
use BaseData;
use ContextableData;
use EmptyData;
use IncludeableData;
use ResponsableData;
use TransformableData;
use ValidateableData;
use WrappableData;
} Event use Spatie\EventSourcing\Commands\AggregateUuid;
class PasswordChanged extends EventWithData
{
public function __construct(
#[AggregateUuid]
public string $userUuid,
public string $password,
) {}
} Command use Spatie\EventSourcing\Commands\HandledBy;
#[HandledBy(AuthAggregate::class)]
class ChangePassword extends PasswordChanged
{
//
} Auth aggregate: public function changePassword(ChangePassword $command): void
{
$this->recordThat(PasswordChanged::from($command->toArray()));
} Usage CommandBus::dispatch(new ChangePassword(
userUuid: $user->uuid,
password: Hash::make($input['password']),
)); |
Beta Was this translation helpful? Give feedback.
-
One gotcha to look out for: if you are doing this in a package make sure you register the LaravelData service provider inside your base test class. |
Beta Was this translation helpful? Give feedback.
-
@ovp87 forgot to share the serializer for the above example: use Spatie\EventSourcing\EventSerializers\JsonEventSerializer;
use Spatie\EventSourcing\StoredEvents\ShouldBeStored;
class DataEventSerializer extends JsonEventSerializer
{
public function serialize(ShouldBeStored $event): string
{
if ($event instanceof EventWithData) {
return $event->toJson();
}
return parent::serialize($event);
}
public function deserialize(string $eventClass, string $json, int $version, ?string $metadata = null): ShouldBeStored
{
if (is_subclass_of($eventClass, EventWithData::class)) {
return $eventClass::from(json_decode($json, true));
}
return parent::deserialize($eventClass, $json, $version, $metadata);
}
} config: // event-sourcing.php
return [
//...
/*
* This class is responsible for serializing events. By default an event will be serialized
* and stored as json. You can customize the class name. A valid serializer
* should implement Spatie\EventSourcing\EventSerializers\EventSerializer.
*/
'event_serializer' => App\DataEventSerializer::class,
//...
]; |
Beta Was this translation helpful? Give feedback.
-
Perhaps a bit of necromancy here, reviving an old post, but i was thinking, is it even a good idea to pass dto's to events in this manner? In my experience dto's have a tendency to change/evolve. Which would obviously become an issue on stored events, and essentially force you to version the dto's in addition to the events. (Or at the very least be VERY mindful about how you change them). Unless im missing something, i guess its likely better to just pass primitives, with versioned events as needed..? |
Beta Was this translation helpful? Give feedback.
It still exists but has been split across multiple traits: https://github.com/spatie/laravel-data/blob/16a842afddd1796d4e322347a4285960895814a9/src/Data.php#L26-L34
For events, I believe you'll need
BaseData
andTransformableData