4

我正在使用 Drupal 服务和 REST 服务器来提供 API。
以前我只使用 1 种类型的响应 JSON,所以我不需要对 URL 进行额外的扩展“.json”。

现在我必须添加新的格式化程序 XML。
然后问题开始了,所有没有任何扩展名(.json 或 .xml)的 API 都将被设置为 XML 的默认输出。

我尝试追踪这个问题,最后发现相关变量是'rest_server_default_response_format'。
服务模块上的相关代码是getResponseFormatContentTypeNegotiations

所以我有 $mime_candidates[] 价值

Array ( [0] => application/xml [1] => text/xml [2] => application/json )

即使 response_format 在第 87 行已设置为 json,但 mimeparse->best_match() 返回 'text/xml'。

覆盖它的最佳方法是什么?
我不认为编辑 getResponseFormatContentTypeNegotiations 是最好的方法。
有没有办法让 best_match 函数更喜欢 JSON 格式而不是 XML 格式?

谢谢你。

4

3 回答 3

1

最好的方法是在您的请求中使用“接受”标头:

Accept: application/json

如果 json 可用,它将被用作响应而不是 xml。

于 2015-06-09T12:11:47.470 回答
1

通过管理 UI,您可以修改配置的服务以仅返回某些格式。

结构> 服务

然后编辑资源 > 服务器选项卡

然后您可以选择响应格式并使其专门为 json。

于 2015-10-10T19:26:54.937 回答
1

在最新版本的服务中,所有动作都发生在getResponseFormatContentTypeNegotiations()文件中services/servers/rest_server/includes/ServicesContentTypeNegotiator.inc;具体来说,这部分:

// Get the best matching format, default to json
$response_format = variable_get('rest_server_default_response_format', 'json');
$http_accept = $context->getServerVariable('HTTP_ACCEPT');
if (!empty($http_accept)) {
  $mime = $this->mimeParse();
  $mime_type = $mime->best_match($mime_candidates, $http_accept);
  $response_format = isset($mime_map[$mime_type]) ? $mime_map[$mime_type] : '';
}

发生的事情是它获得了 JSON 的默认格式化程序。然后它正在查看您的请求的接受标头。如果您的接受标头未指定有效的 MIME 类型,它将使用 JSON。

似乎所有现代浏览器都具有称为“内容协商”的功能,默认情况下,它们基本上指定它们首先接受 HTML,然后是 XML(尽管这因浏览器而异)。

因此,考虑到这一点,您会期望客户端只需从其请求标头中删除 XML 模拟类型即可获取 JSON。不幸的是,并非如此。

如果请求包含任何“接受”标头,代码将尝试将标头与您启用的解析器列表相匹配(假设它只是 XML、JSON),它会选择一个匹配的,或者第一。因此,如果您确实有一个接受标头并且没有指定有效的 MIME 类型,服务将使用您启用的第一个

要更改您启用的那些解析器的顺序,我认为您可以使用来自services.alter.api.php.

于 2016-02-13T08:47:06.610 回答