我在Symfony 4中使用FOSRestBundle到API项目。我使用注释并在控制器中我有例如
use FOS\RestBundle\Controller\Annotations as Rest;
/**
* @Rest\Get("/api/user", name="index",)
* @param UserRepository $userRepository
* @return array
*/
public function index(UserRepository $userRepository): array
{
return ['status' => 'OK', 'data' => ['users' => $userRepository->findAll()]];
}
配置/包/ fos_rest.yaml
fos_rest:
body_listener: true
format_listener:
rules:
- { path: '^/api', priorities: ['json'], fallback_format: json, prefer_extension: false }
param_fetcher_listener: true
view:
view_response_listener: 'force'
formats:
json: true
现在我想在我的回复中添加自定义标题'X-Total-Found'。怎么做?
答案 0 :(得分:1)
您依赖于FOSRestBundle ViewListener,因此为您提供了有限的选项,例如无法传递自定义标头。为了达到您想要的效果,您需要从控制器中调用$this->handleView()
并将其传递给有效的View
实例。
您可以使用View :: create()工厂方法或控制器$this->view()
快捷方式。两者都将数据数组,状态代码和响应头数组作为参数。然后,您可以在那里设置自定义标题,但每次调用都必须这样做。
您拥有的另一个更易于维护的选项是注册on_kernel_response
事件侦听器/订阅者,并以某种方式传递自定义标头的值(例如,您可以将其存储在请求属性中)。 / p>
这是您拥有的两个选项。你可能有第三个,但我不能在一分钟拿出来。
答案 1 :(得分:0)
我遇到了同样的问题。我们希望将分页元信息移动到标题中,并使响应不带信封(数据和元属性)。
我的环境
第 1 步:创建一个对象来保存标题信息
// src/Rest/ResponseHeaderBag.php
namespace App\Rest;
/**
* Store header information generated in the controller. This same
* object is used in the response subscriber.
* @package App\Rest
*/
class ResponseHeaderBag
{
protected array $data = [];
/**
* @return array
*/
public function getData(): array
{
return $this->data;
}
/**
* @param array $data
* @return ResponseHeaderBag
*/
public function setData(array $data): ResponseHeaderBag
{
$this->data = $data;
return $this;
}
public function addData(string $key, $datum): ResponseHeaderBag
{
$this->data[$key] = $datum;
return $this;
}
}
第 2 步:将 ResponseHeaderBag 注入控制器动作
public function searchCustomers(
ResponseHeaderBag $responseHeaderBag
): array {
...
...
...
// replace magic strings and numbers with class constants and real values.
$responseHeaderBag->add('X-Pagination-Count', 8392);
...
...
...
}
第 3 步:注册订阅者并监听响应内核事件
// config/services.yaml
App\EventListener\ResponseSubscriber:
tags:
- kernel.event_subscriber
订阅者是监听事件的好方法。
// src/EventListener/ResponseSubscriber
namespace App\EventListener;
use App\Rest\ResponseHeaderBag;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
class ResponseSubscriber implements EventSubscriberInterface
{
public function __construct(
protected ResponseHeaderBag $responseHeaderBag
){
}
/**
* @inheritDoc
*/
public static function getSubscribedEvents()
{
return [
KernelEvents::RESPONSE => ['addAdditionalResponseHeaders']
];
}
/**
* Add the response headers created elsewhere in the code.
* @param ResponseEvent $event
*/
public function addAdditionalResponseHeaders(ResponseEvent $event): void
{
$response = $event->getResponse();
foreach ($this->responseHeaderBag->getData() as $key => $datum) {
$response->headers->set($key, $datum);
}
}
}