-
Notifications
You must be signed in to change notification settings - Fork 46
Description
Apologies if there is a better way to submit such open-ended questions. In this case, please let me know or simply close the issue.
What I want to do
I want to adopt event sourcing (via verbs) for my application that is using laravel-json-api (the go-to package I don't want to live without).
In essence, it means that there should not be any direct model creation, but I would fire events instead with the relevant request data.
Given that everything would still be backed by Eloquent models, I think the existing implementation is a great start for all read and the main thing that would differ is how I create/update my models.
FYI: I have not yet extensively thought about or researched how well REST/JSON:API and event sourcing go together.
But from a conceptual point of view, I don't see any conflict at this point.
What I'm currently doing
I'm currently simply implementing custom controller actions to hand over the validated data to my events.
I ensure that my events are "committed" to be reflected in the DB and then I simply query and return the eloquent model I expected to be created via the event.
Example:
// routes/api.php
JsonApiRoute::server('v0')
->prefix('v0')
->resources(function (ResourceRegistrar $server) {
$server
->resource('posts', PostController::class)
->only('store', 'index', 'read');
});
// app/Http/Controllers/Api/V0/PostController.php
// ...
public function store(Route $route, StoreContract $store)
{
$request = ResourceRequest::forResource(
$resourceType = $route->resourceType()
);
$data = $request->validated();
PostCreated::fire(
post_id: $postId = snowflake_id(),
title: $data['title'],
body: $data['body'],
);
Verbs::commit();
return DataResponse::make(Post::find($postId)->sole())
->withQueryParameters(ResourceQuery::queryOne($resourceType))
->didCreate();
}
// ...
What I Imagine
I was thinking about if/how I should eventually implement my own "non-eloquent" Resource (?), where I would somehow be mapping schemas to event states. Or maybe I should keep the mapping to Eloquent models, but somehow be able map certain API routes/actions to certain events being fired instead of the mapped eloquent models to be updated directly.
I think I would need to put some more thought into this to understand the different moving parts, but for now I was wondering how I could:
- Fully replace any create/update logic with custom logic to fire events
- Still utilize the Eloquent implementation for all API read operations.
I acknowledge that this is a long-winded post. In essence, I would like to
- Validate that my current approach is idiomatic in regards to this package
- How I would move forward with my approach to turn it into a custom extension that supports event sourcing more declaratively, if even possible. I imagine that I could reuse most (all?) of the Eloquent related read logic for this and only adjust the create/update parts.