如何扩展 FOSRestBundle RequestBodyParamConverter?

Posted

技术标签:

【中文标题】如何扩展 FOSRestBundle RequestBodyParamConverter?【英文标题】:How to extend FOSRestBundle RequestBodyParamConverter? 【发布时间】:2021-10-14 01:24:48 【问题描述】:

我是 Symfony (5.3) 的新手,想扩展 RequestBodyParamConverter (FOSRestBundle 3.0.5) 以创建 REST api。将 @ParamConverter 注释与 RequestBodyParamConverter 一起使用可以正常工作。但是,我想创建一个自定义转换器,它与RequestBodyParamConverter 完成完全相同的工作,外加一些额外的工作。

我的第一个猜测是简单地扩展 RequestBodyParamConverter 并在 @ParamConverter 注释中提供我的自定义子类。但是,RequestBodyParamConverter 被定义为final,因此无法扩展...

RequestBodyParamConverter / fos_rest.request_body_converter 注入自定义转换器类(参见下面的示例)也会失败,因为找不到服务。我认为这是因为它被定义为 private?

所以,我的最后一个想法是在我的自定义转换器类中创建一个RequestBodyParamConverter。虽然这可行,但我不确定这是否是解决此问题的正确方法。这样RequestBodyParamConverter 被创建了两次。这当然没什么特别的,但这是 Symfony 解决这个问题的方式还是有其他解决方案?

示例:

在自定义转换器类中注入RequestBodyParamConverter

class MyParamConverter implements ParamConverterInterface 
    protected $parentConverter;
    public function __construct(ParamConverterInterface $parentConverter) 
        $this->parentConverter = $parentConverter;
    

    public function apply(Request $request, ParamConverter $configuration): bool 
        doExtraWork();
        return $this->parentConverter->apply(...);
    


// config/services.yaml
My\Project\MyParamConverter:
    tags:
        -  name: request.param_converter, converter: my_converter.request_body 
    arguments:
        # both fails since service is not found
        $parentConverter: '@FOS\RestBundle\Request\RequestBodyParamConverter'

        # OR

        $parentConverter: '@fos_rest.request_body_converter'

在自定义转换器类中创建RequestBodyParamConverter

class MyParamConverter implements ParamConverterInterface 
    protected $parentConverter;
    public function __construct(...parameters necessary to create converter...) 
        $this->parentConverter = new RequestBodyParamConverter(...);
    

    ...

【问题讨论】:

【参考方案1】:

Symfony 提供了decorate a registered service 的方法

要使用它,您需要在容器中注册的 FOS 服务 ID。

要获取它,您可以使用此命令

symfony console debug:container --tag=request.param_converter

检索您要覆盖的服务的Service ID

然后你可以配置你的服务来装饰 FOS 一个

My\Project\MyParamConverter:
    decorates: 'TheIdOf_FOS_ParamConverterService'
    arguments: [ '@My\Project\MyParamConverter.inner' ] # <-- this is the instance of fos service

也许您需要在此声明中添加tags,我不确定。

如果您遇到错误,请告诉我。

【讨论】:

以上是关于如何扩展 FOSRestBundle RequestBodyParamConverter?的主要内容,如果未能解决你的问题,请参考以下文章

Symfony + FOSRestBundle - 如何允许 NULL 值到配置有自定义表单类型的字段?

如何轻松登录、Symfony2 Security、FOSUserBundle、FOSRestBundle?

如何从SonataMediaBundle的图库中获取图像网址,以便与FOSRestBundle一起使用?

无法使用 FOSRestBundle

无法使用 Symfony 5 安装 FOSRestBundle

FOSRestBundle 不加载路由