Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony 3 restrict controller action to to consume specific content type

Tags:

symfony

can be controller action in SF3 annotated to consume specific 'Content-Type'?

I'am trying to abandon '/api/post/{id}/xml' route hack.

namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
class BlogApiController extends Controller
{
/**
 * @Route("/api/posts/{id}")
 * @Method({"GET","HEAD"})
 * some-magic-annotation-here
 */
public function showJson($id)
{
    // response in json
}

/**
 * @Route("/api/posts/{id}")
 * @Method({"GET","HEAD"})
 * some-magic-annotation-here
 */
public function showXml($id)
{
    // response in XML
}
}
like image 634
Jan Tajovsky Avatar asked Sep 17 '25 21:09

Jan Tajovsky


2 Answers

According the the official documentation you can use condition param:

/**
 * @Route(
 *     "/api/posts/{id}",
 *     condition="request.headers.get('Content-Type') === 'application/json'"
 * )
 * @Method({"GET","HEAD"})
 */
public function showJson($id)
{
    ...

Same thing for XML.

In condition you have to use expression syntax

like image 169
Szymon Dudziak Avatar answered Sep 22 '25 10:09

Szymon Dudziak


Use the _format:

class BlogApiController extends Controller
{
    /**
     * @Route("/api/posts/{id}.{_format}", defaults={"_format": "json"})
     * @Method({"GET","HEAD"})
     */
    public function getPost($id, $_format)
    {
        // Retrieve your object

        if ('xml' == $_format) {
            return $this->showXml($object);
        }

        return $this->showJson($object);
    }
}

If you need to check the content-type of the incoming request:

$contentType = $request->headers->get('Content-Type');

if (0 === strpos($contentType, 'application/json')) {
    return $this->showJson($object);
} elseif (0 === strpos($contentType, 'application/xml')) {
    return $this->showXml($object);
}

In a next time, if you don't already use it, you should use the Serializer component rather and remove the two show[format] methods, for example:

$encoders = array(new XmlEncoder(), new JsonEncoder());
$normalizers = array(new ObjectNormalizer());
$serializer = new Serializer($normalizers, $encoders);

$responseBody = $serializer->serialize($object, $_format);
like image 22
chalasr Avatar answered Sep 22 '25 10:09

chalasr