Home > Net >  Symfony-Giving all api responses according to content type
Symfony-Giving all api responses according to content type

Time:01-25

routes.yaml routes.yaml

Whatever the content type is, I want the response to be of that type. How can I do it?

I want it to be response, by content type. I want to do it globally. For example; If the content type is json, the response must be json. If the content type is XML, the response should return XML. or if the content type is xxx the response should return xxx

The system itself should automatically determine the return type according to the content-type. Is this possible in symfony? Because Symfony returns exceptions in xml format by default. If the api user sends the content-type as json and receives an exception, it receives it as xml. I dont want this.

I can write _format json or xml. But I want it to be dynamic

CodePudding user response:

Check how HttpKernel is handling response.


To have response type dynamically respond to client sent Accept header you must write some kind of mapper for it.

You should write some subscriber/listener to transform your response to needed format:


use Symfony\Component\EventDispatcher\EventSubscriberInterface;

final class ResponseSubscriber implements EventSubscriberInterface
{
    public function __contstruct(private Request $request) {}

    public static function getSubscribedEvents(): array
    {
        return [
            KernelEvents::RESPONSE => 'onResponse',
        ];
    }

    public function onResponse(ResponseEvent $event): void
    {
        // Skip on internal requests. E.g. redirect
        if (!$event->isMainRequest()) {
            return;
        }

        $data = $event->getResponse();

        $requestedType = $this->request->headers->has('Accept')
            ? $this->request->headers->get('Accept')
            : 'application/json';

        $response = match ($requestedType) {
             'application/json' => $this->getJsonResponse($data),
             'application/xml' => $this->getXmlResponse($data),
             'text/html' => $this->getHtmlResponse($data),
             ...
             default => throw new \InternalException('Request type ' . $requestedType . ' is not supported'), // This better be checked on KernelEvents::REQUEST
        }

        $event->stopPropagation();
        $response->setResponse($response);
    }
}

You can use XDebug to do step-debugging and see where your response data is travelling for better understanding of Symfony internals.

  • Related