FOSRestBundle -在参数包中注入主体参数是一个很好的实践



我们正在使用FOS Rest包,并且,起初,我们不知道主体侦听器是活动的。

同时,我们创建了很多通过body接收数据的JSON格式的资源。目前我们只支持JSON格式。现在控制器中的很多都是从Symfony ParameterBag中检索参数,因为body listener在那里注入了它们。

所以,你认为这是一个很好的做法,把责任留给body listener,并在控制器中通过参数包检索参数?这样,无论通过GET、POST还是body,所有参数都通过参数包到达控制器。

我们正在关注这个问题,因为我们的一些API客户端在发出请求时没有在header中提供内容类型,因此,body侦听器没有在参数包中注入body。所以在控制器中我们没有可用的参数。

提前感谢!

一般来说,API设计的一个最重要的方面应该是实现中的一致性,以便您的使用者了解如何与您的系统交互。为此,我将遵循以下模式:

  • 如果身体监听器对你的发展有帮助,保持它的开启状态;这个监听器是帮助您编写更简单控制器的快捷方式,所以如果它适合您,就没有理由放弃它
  • 对于期望JSON请求体的API端点,如果缺少适当的Content-type: application/json标头(可以通过在路由上设置_format要求来完成),则向消费者报告他们正在进行非法请求;参见高级路由示例)
  • 如果你必须支持这些不传递报头的遗留用户,你可以在kernel.request事件上创建一个监听器,具有非常高的优先级,它只是检查检测到的mime类型,如果它缺失,做这样的事情:

    if ($request->getRequestFormat() != 'json') {
        json_decode($request->getContent());
        if (json_last_error() == JSON_ERROR_NONE) {
            $request->setRequestFormat('json');
        }
    }
    

    (这里json_last_error()的使用并不完善;

  • 最后,如果您还没有,请确保您将API控制器限制为正确的请求方法,再次确保它们被正确使用,并使您的开发和使用更加一致。例如,如果您正在使用注释,这就像使用fosrestbundle提供的@Get@Post等来代替通常的@Route一样简单。如果您使用的是YML或XML配置,则是methods属性。

    尽管单个控制器当然可以通过GET(带请求参数)、POST(通过url编码的表单数据)或POSTPUT接受JSON数据和体侦听器转换的数据,但这使得API非常复杂,因为您必须开始维护这些不同的情况,我认为事情对您的用户来说也变得非常困难。

作为这些API的消费者,如果我在请求体中传递JSON但不包括适当的头,我预计我的请求会失败,如果我将x-www-form-urlencode数据传递给基于JSON的API,我预计我的请求会失败。总的来说,对于API的维护者和消费者来说,严格要求您接受的内容并始终遵循相同的模式是一个好主意。

最新更新