Reputation: 23
I am trying to create a listener that configures the Response
using annotations and sets the response content as the controller return.
The Controller code:
use PmtVct\PhotoBookBundle\Annotations\ResponseType;
use Symfony\Component\HttpFoundation\Request;
/**
* @ResponseType("JSON")
*/
public function home(Request $request) {
return ['asdf' => 123];
}
But I receive the 'The controller must return a response
' error.
There is a way to return an array on Controller
instead a Response
?
Upvotes: 2
Views: 3511
Reputation: 506
Explain https://stackoverflow.com/a/46007749/21333278:
Controller:
class YourController extends AbstractController
{
#[Route('your/route', methods: ['GET'])]
public function __invoke(): YourRouteResponseDTO
{
return new YourRouteResponseDTO();
}
}
Instead of YourRouteResponseDTO class, you can use an array, but the more typing, the better.
class YourRouteResponseDTO implements ResponseJsonInterface
{
public int $param1;
public YourAnotherResponseDTO $param2;
}
And listener
namespace App\Listener;
use App\Contract\ResponseJsonInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\Serializer\SerializerInterface;
class ResponseListener
{
public function __construct(
private readonly SerializerInterface $serializer,
) {
}
public function __invoke(ViewEvent $event): void
{
$response = $event->getControllerResult();
if (!($response instanceof ResponseJsonInterface)) {
return;
}
$jsonResponse = $this->json($response);
$event->setResponse($jsonResponse);
}
protected function json(mixed $data, int $status = 200, array $headers = [], array $context = []): JsonResponse
{
$json = $this->serializer->serialize($data, 'json', array_merge([
'json_encode_options' => JsonResponse::DEFAULT_ENCODING_OPTIONS
| JSON_UNESCAPED_UNICODE
| JSON_UNESCAPED_SLASHES
| JSON_PRETTY_PRINT,
], $context));
return new JsonResponse($json, $status, $headers, true);
}
}
#services.yaml
services
App\Listener\ResponseListener:
tags:
- { name: kernel.event_listener, event: kernel.view, priority: 10 }
Upvotes: 1
Reputation: 1674
You are trying to do a similar thing to FOSRestBundle. Maybe consider using this bundle? It will allow:
In case you still want to build such listener yourself - look how it's done in FOSRestBundle - https://github.com/FriendsOfSymfony/FOSRestBundle/blob/master/EventListener/ViewResponseListener.php - they are using "kernel.view" event.
Upvotes: 2
Reputation: 35
According to the documentation you can return a JsonResponse like this:
return new JsonResponse(['asdf' => 123]);
Upvotes: 0