FOSRestBundle - 在参数包中注入 body 参数是一个好习惯吗?

FOSRestBundle - is a good practice to inject body params in the parameter bag?

我们使用的是 FOS Rest 包,起初我们没有意识到 body 侦听器处于活动状态。

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

那么,您认为将此责任留给 body 侦听器并在控制器中通过参数包检索参数是一种好做法吗?这样无论是GET,POST还是body,所有的参数都是通过参数包到达控制器的。

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

提前致谢!

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

  • 如果 body 侦听器有助于您的开发,请保持启用状态;这个监听器是帮助你编写更简单控制器的捷径,所以如果它对你有用,就没有理由放弃它
  • 对于期望 JSON 请求 body 的 API 端点,如果正确 Content-type: application/json header,则向消费者报告他们正在发出非法请求] 丢失(这可以通过在路线上设置 _format 要求来完成;参见 advanced routing example
  • 如果您必须支持这些未通过 header 的旧用户,您可以在 kernel.request 事件上创建一个具有非常高优先级的侦听器,它只检查检测到的 MIME 类型,如果缺少,则执行如下操作:

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

    (这里 json_last_error() 的使用并不完美;请参阅 this question 以获得更详细的讨论。)

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

    尽管单个控制器当然可以通过 GET(带有请求参数)、POST(通过 URL-encoded 表单数据)或 POST or PUT with JSON data and a body listener-conversion, 这使得 API 非常复杂,因为你必须开始维护这些不同的案例,我认为对于您的用户来说,事情也会变得非常困难。

作为这些 API 的消费者,如果我在请求 body 中传递 JSON 但不包括正确的 header,我预计我的请求会失败],如果我将 x-www-form-urlencode 数据传递给 JSON-based API,我预计我的请求会失败。总的来说,对于 API 的维护者和消费者来说,最好严格遵守您接受的内容并始终遵循相同的模式。