In some scenarios, I need to listen to kernel.request or kernel.view events with a specific priority (cf. EventPriorities) but only for 1 method, for instance:
public function foo(GetResponseForControllerResultEvent $event)
{
if ('api_users_foo_collection' !== $event->getRequest()->attributes->get('_route')) {
return;
}
// do some wonderful and incredible code you cannot imagine
}
This method will be called at every kernel.view event, but I don't need to: I just need it to be called on my ApiResource method foo, on the kernel.view event with a custom priority (optional).
I was thinking about something similar to the DoctrineEventListeners: a ResourceEventSubscriber which can be directly applied on my method:
/**
* @ApiResource(collectionOperations={
* "get"={"method"="GET"},
* "post"={"method"="POST", "subscribers"={
* "kernel.request"={
* {"class"="App\ResourceSubscriber\FooResourceSubscriber", "method"="foo", "priority"=90}
* }
* }
* })
*/
class Foo
Different syntaxes could be possible:
{"class"="App\ResourceSubscriber\FooResourceSubscriber", "method"="foo", "priority"=90}
{"class"="App\ResourceSubscriber\FooResourceSubscriber", "method"="foo"} # default priority = 0
{"App\ResourceSubscriber\FooResourceSubscriber::foo"}
{"App\ResourceSubscriber\FooResourceSubscriber"} # using __invoke method
The resource subscriber method could receive a GetResponseEvent or a custom event with the data and the request (and more if necessary).
This could optimize performances, and prevent to test the route name in a kernel event.
What do you think @api-platform/core-team ?
+1 Though I wonder if the performance improvement is really worth the implementation.
At least, it will prevent the if ('api_users_foo_collection' !== $event->getRequest()->attributes->get('_route')) 😉
I'll try to open a PR
Please create a benchmark before opening a PR. I'm pretty sure that
if ('api_users_foo_collection' !== $event->getRequest()->attributes->get('_route')) {
return;
}
costs almost nothing. Introducing such complexity must worth the performance gain (so it should be measured first).
I wanted this today. I think it would be a nice feature.
The problem with the current impl as suggested is you are hard coding route names. if your route name was to change, you need to remember to update your hard coded routes. (but your tests will catch the problem though right?)
There is no need to hard code the route name. A combination of the resource name and the operation name should work, no?
Let's close this, feel free to follow #2506