-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ability to include metadata on every event #14
Add ability to include metadata on every event #14
Conversation
Signed-off-by: Skyler Katz <skylerkatz@hey.com>
I love this, and definitely want something like this in Verbs. My one question is: do we want metadata to just be a plain array, or do we want to use a collection or bespoke |
I figured a basic array was the easiest thing without overcomplicating it. A collection might be nice as well. If we did a full class, maybe it makes sense to put a second column on the event table for metadata and then we can use a custom eloquent cast. |
Just throwing some unstructured thoughts out there:
|
So I could see doing kinda the best of both worlds. We could introduce a class Metadata
{
protected Collection $extra;
public function __construct(array $data = [])
{
// 1. Populate any properties that exist using our serializer
// 2. Push remaining data into $this->extra
}
public function __get(string $name)
{
return $this->extra->get($name);
}
public function __set(string $name, $value): void
{
$this->extra->put($name, $value);
}
public function __isset(string $name): bool
{
return $this->extra->has($name);
}
} And by default we would populate namespace App\Events\Support;
class Metadata extends \Verbs\Metadata
{
public ?string $user_agent = null;
public ?string $ip_address = null;
public ?int $active_user_id = null;
} And then in your config you'd set Once that's all hooked up, you could just typehint the public function handle(App\Events\Support\Metadata $metadata) {
// Now I have my typed metadata object
} And Verbs could handle the DI for you. But if you don't want/need a custom metadata object, you could just type hint the base class and it'd still work. The upside of this is that a package could rely on metadata always being there without having to know its type ahead of time. A package could just dump values into the metadata payload, and if the end user wanted to access them with type safety, all they would have to do is add properties to their custom class. |
I really like that approach. The EventStore::createMetadataUsing(function (string $event_class, App\Support\Metadata $metadata) {
$metadata->request_id = (string) Str::uuid();
return $metadata;
}); So you could still sprinkle |
Yeah, that's cool. We could definitely support type-hinting either version in the What's your thinking for wanting the event class in the callback? I would think that anything that's event-specific would live in the event, right? I would think that any global callbacks should only apply global metadata… |
It is a bit of a holdover from the But it's a bit of a contrived example |
@skylerkatz @inxilpro how far from yes-yes-yes are you two on this feature? I think I'm ok with the implementation you guys were discussing in the comments. Are we in agreement and just need to implement? Or is there a substantive disagreement still? |
I think we're pretty good. @skylerkatz — you want to take a stab at switching to a class-based approach? I think for the first version we could skip the custom DI stuff, and just know that we want to add that eventually. |
I think we are just on the "needs to implement stage". Which I plan on working on this week. |
Signed-off-by: Skyler Katz <skylerkatz@hey.com>
Signed-off-by: Skyler Katz <skylerkatz@hey.com>
Signed-off-by: Skyler Katz <skylerkatz@hey.com>
Signed-off-by: Skyler Katz <skylerkatz@hey.com>
@inxilpro I pushed up an initial implementation at a I think it may just be an organization thing, but would love your thoughts on it. |
Somehow I missed this! Looking thru it now, my main question is why not store metadata on the event object? We can chat about this tomorrow maybe! |
A new class, MetadataManager, was added to manage the creation and manipulation of Metadata instances across different components. As part of this update, existing event and metadata handling code were refactored to utilize the new MetadataManager. The Metadata class now also implements the ArrayAccess interface, providing array-like access to its properties. Co-Authored-By: Skyler Katz <skylerkatz@hey.com>
The metadata creation documentation has been updated to illustrate a change in the createMetadataUsing method. The example now shows how to directly set the 'team_id' on the Metadata object. It also demonstrates the option of returning an array for automatic metadata merging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a good approach.
I find myself wanting to include some additional data to every event, even though the data is not entirely related to the event itself.
For example, in a
Middleware
I generate a uniquerequest_id
and I want that included in every event. I also want to include the currentTeam
that the authenticated user is making the request in.The implementation follows very closely to the way Laravel handles this in their
Queue::createPayloadUsing()
function.I also added some docs, but not sure if this deserves its own page, vs somewhere else on an existing page.