I'm using FOS Rest Bundle for my RESTful API, I want to override the responses returned from my ApiController, example:
php
/**
* @QueryParam(name="sourceAddr", strict=true, requirements="[0-9]{8}", description="Do things")
* @param $paramFetcher ParamFetcher
* @return array
* @throws MtBoxApiException
*/
public function getAuthAction(ParamFetcher $paramFetcher)
{
return [
'rfid' => '445545454',
'fName' => 'adazda',
'lName' => '8888888',
'prod' => 75
];
}
What I want is adding additional data to the returned responses, so I want to intercept these responses and override them based on some conditions.
The final result that I want the api returns:
{
someAdditionalData1: value1,
someAdditionalData2: value2,
data: {
//the data returned by the controller action
}
}
For an idea how this is done you can look at the FOS\RestBundle\EventListener\ViewResponseListener
class. They register this class as an event subscriber. You can register your class in the same way in your services.yml
test_response_listener:
class: MyBundle\EventListener\MyViewResponseListener
tags:
- { name: kernel.event_subscriber }
You need to ensure your class implements Symfony\Component\EventDispatcher\EventSubscriberInterface
and contains the method getSubscribedEvents
like this:
public static function getSubscribedEvents()
{
return array(
KernelEvents::VIEW => array('onKernelView', 50),
);
}
The event is 'onKernelView', i.e. when a view is returned. This will only be called if the response from the controller is not actually a Response object. In my test of this I returned a User object so it was called. The "50" represents the priority. If you don't put it higher than 30 then the FOSRestBundle listener will be called first and will set the response. If any of these listeners call $event->setResponse
then the other ones are ignored so make sure you don't do it in your method or the FOSRest one won't be called.
The onKernelView
is the name of the method to be called. It will receive a certain type of event so make your method signature like this:
public function onKernelView(GetResponseForControllerResultEvent $event)
Now, finally, what you want to do is unify the response format. You can do this by changing the controller result of the event inside your listener method to match the format you want:
$event->setControllerResult([
'foo' => 'bar',
'data' => $event->getControllerResult()
]);
If you have the serializer set up it should still serialize your controller result as normal, but you'll get the added data in the response.