Reputation: 7602
I'm working on an app that I want to offer both JSON and HTML responses. Here's an example action method:
/**
* Lists all Boards entities.
*
* @Route("/", name="boards")
* @Method("GET")
* @Template()
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('ScrumBoardServiceBundle:Boards')->findAll();
$acceptHeader = strtolower($this->getRequest()->headers->get('Accept'));
if ($acceptHeader === 'application/json') {
$serializer = new Serializer(array(new GetSetMethodNormalizer()), array('json' => new
JsonEncoder()));
$response = $serializer->serialize(array('success' => true, 'data' => array(
'entity' => $entities,
)), 'json');
$result = new Response($response, 200, array('Content-Type' => 'application/json'));
} else {
$result = array(
'entities' => $entities,
);
}
return $result;
}
This works fine. If you send in an HTTP Accept header that is exactly application/json
, you will get JSON back. Otherwise, you get the usual hTML view.
This works fine, but I've got dozens of actions. I'd rather not repeat myself. I'm working on refactoring this code into something a little more generic... but I'm also wondering if this problem has already been solved by an existing Symfony2 bundle. Maybe something with annotations? Or a config setting? I haven't been able to find anything so far. But I am so new to Symfony I could very easily be missing something.
Upvotes: 2
Views: 24803
Reputation: 3370
As a generic idea, in case you want to avoid using 3rd party bundles, you may subscribe to the kernel.response event and play with the Response there, just in one common place.
Something like:
//services.yml
services:
my.kernel.listener:
class: Acme\Bundle\AppBundle\EventListener\MyKernelListener
tags:
- { name: kernel.event_listener, event: kernel.response, method: onKernelResponse }
// MyKernelListener.php
class MyKernelListener
{
public function onKernelResponse(FilterResponseEvent $event)
{
$response = $event->getResponse();
$request = $event->getRequest();
// ... your logic ...
}
}
Upvotes: 2
Reputation: 52493
The bundle you are looking for is the FOSRestBundle.
You can have it serve JSON based on Accept header or adding _format to your routes ... highly configurable.
Works nice with JMSSerializerBundle.
Upvotes: 1