[LiveComponent] Exposing public objects via emit()
Hi 👋🏻
Small suggestion to improve the current usage of ComponentToolsTrait::emit(), for now, the method defines the following signature:
public function emit(string $eventName, array $data = [], ?string $componentName = null): void
{
$this->liveResponder->emit($eventName, $data, $componentName);
}
The main issue here IMHO is the usage of $data, AFAIK, we can only pass arrays of scalars, this prevent us from using objects when communicating between components using only the PHP approach (without emitting from the JS code), I'm not sure how it can be improved (after discussing with @smnandre, maybe we can use a new attribute #[ExposedStimulusObject] for example, this attribute would allow us to say that this object is serialized/deserialized when emitting the event and that if it contains sensitive data, we're fully responsible for any leak) but I think it could be a good idea as we sometimes want to emit events that contains objects (think of notifications, ValueObject's, DTO's, etc).
Any thoughts? 🙂
PS: This approach would not allow to emit event with objects from the frontend (as we need to obtain and keep the FQCN of the object to serialize/deserialize) but this kind of use case if strongly tied to the PHP usage of the emit method.
Hey! It looks like if we want to implement this feature we have to resolve #1587 first. I think this can be a great idea. The thing is @smnandre in the issue I linked, mentioned some security by exposing too much data... I think we can implement this can of feature with a big red flag on the doc. What do you think?
What i like in the idea of @Guikingone is that using an dedicated attribute is an active choice, that cannot hide some unwanted / hidden behaviour
@WebMamba I think a notice in the documentation is not enough, most of the time, a developer will see that it can trigger an event with an object, will do it and will come crying like a baby because "critical data" has leaked (sorry to say things like that but that's the case most of the time 😅).
That's why having an attribute is a better idea IMHO, we can easily trigger an exception / warning if the attribute is not used in the object sent via emit() and inform the developer that something is missing.
Again, if you have a better idea, I'm open to discuss about it 🙂
Thank you for this suggestion. There has not been a lot of activity here for a while. Would you still like to see this feature? Every feature is developed by the community. Perhaps someone would like to try? You can read how to contribute to get started.
Could I get an answer? If I do not hear anything I will assume this issue is resolved or abandoned. Please get back to me <3
Hey,
I didn't hear anything so I'm going to close it. Feel free to comment if this is still relevant, I can always reopen!
Hello,
about @smnandre remark in https://github.com/symfony/ux/issues/1587
And to be honest passing full object in Events is like passing full object in Messenger messages.... not something i'd recommand.
I think if only DTOs are passed, this is totally acceptable, isn't it?
It seems that passing DTOs to the event is already kinda supported, but in the event side the object is not denormalized back:
#[LiveAction]
public function save(LiveResponder $responder): void {
$responder->emitUp('foo:save', [
'blogPost' => new BlogPost($id, $title),
]);
}
#[LiveListener('foo:save')]
public function saveMandatoryDataSection(#[LiveArg] mixed $blogPost): void
{
// here, `$blogPost` is a "normalized" array representing the DTO
}
Maybe we could add a parameter useSerializerForHydration to LiveArg?
And by the way, I don't understand the security concerns here, since passing a DTO is somehow already supported
I'd really like this feature to be available, maybe I can give a try for the implementation?
thanks for your answer :)
We need to refactor the entire hydration/serialisation system sooner than later (TypeInfo, etc) ... but a first version or DTO in events before UX 3 (if that does not change too many things internally), it's a 100% yes!
Regarding the security part, many people do not realize the entire data would be then accessible in the document HTML, exposing things they probably will not want to (credential, internal details, etc etc) as these events are transported through the DOM and not messenger. We cannot forbid entities but that would not be something I'd like to see documented, and maybe even warned againsts.
A DTO is something else (by definition, it contains data hand-picked to be sent) :)
but a first version or DTO in events before UX 3 (if that does not change too many things internally), it's a 100% yes!
yeah nice, I'll give it a try at some point :)
Regarding the security part [...]
yeah I totally understand, and my only wish would be to enable DTO usage. But I think Pandora's box is already opened, since it is already possible to pass an object to an event - the only missing piece being denormalization as a parameter of the listener - then it is already possible to expose entities in an event, and restricting this usage would be a BC break...
Then, fully supporting objects as event parameters would allow to document this feature and prevent users about how they should not abuse it 😁
About the implementation, do you think adding a useSerializerForHydration parameter to LiveArg attribute is the way to go?
Thank you for this suggestion. There has not been a lot of activity here for a while. Would you still like to see this feature? Every feature is developed by the community. Perhaps someone would like to try? You can read how to contribute to get started.
Hello? This issue is about to be closed if nobody replies.
Hey,
I didn't hear anything so I'm going to close it. Feel free to comment if this is still relevant, I can always reopen!