我遵循了本教程:http://pingv.com/blog/an-introduction-drupal-7-restful-services在评论中,似乎每个人都有和我一样的问题。
我用drupal服务模块做了一个休息服务:服务器=RESTpath=api/mohtadoon
mohtadoon_api.module文件
<?php
/**
* Implements of hook_services_resources().
*/
function mohtadoon_api_services_resources() {
$api = array(
'mohtadoon' => array(
'operations' => array(
'retrieve' => array(
'help' => 'Retrieves mohtadoon data',
'callback' => 'mohtadoon_api_stories_retrieve',
'file' => array('file' => 'inc', 'module' => 'mohtadoon_api','name' => 'resources/mohtadoon_api'),
'access arguments' => array('access content'),
),
),
),
);
return $api;
}
资源中的mohtadoon_pi.inc文件/mohtadoon_pi路径
<?php
function mohtadoon_api_stories_retrieve() {
return mohtadoon_api_find_stories();
}
function mohtadoon_api_find_stories() {
// Compose query
$query = db_select('node', 'n');
$query->join('node_revision', 'v', '(n.nid = v.nid) AND (n.vid = v.vid)');
$query->join('users', 'u', 'n.uid = u.uid');
$query->join('field_data_body', 'b', '((b.entity_type = 'node') AND (b.entity_id = n.nid) AND (b.revision_id = n.vid))');
$query->fields('v', array('timestamp', 'title'));
$query->addField('u', 'name', 'author');
$query->addField('b', 'body_value', 'content');
$query->condition('n.type', 'stories', '=');
$items = $query->execute()->fetchAll();
return $items;
}
?>
当我访问路径时
http://localhost/mohtadoon01/?q=api/mohtadoon/retrieve
其中mohtadon01是项目路径AND?q=因为
请求结果为404未找到:找不到资源检索。
为什么会发生这种情况&;如何调试这样的东西。。。我以前没有和drupal打过交道,只想让一个得到web服务。
您可能需要对字符串进行url编码:
http://localhost/mohtadoon01/?q=api%2Fmohtadoon%2Fretrieve
但不能保证这会起作用,这取决于你的drupal配置。
根据RFC,查询字符串中允许使用斜线:http://ietf.org/rfc/rfc3986.txt,但是许多现成的服务没有:您可能需要启用AllowEncodedSlaches。
我在使用Services7.x-3.7时遇到了完全相同的事情。为了理解这个问题,我查看了以下文件:
services/servers/rest_server/includes/RESTServer.inc
给定服务的定义,GET请求对资源执行的代码应该是:
protected function resolveController($resource, &$operation) {
...
if ( $request_method == 'GET'
&& $canon_path_count >= 1
&& isset($resource['operations']['retrieve'])
&& $this->checkNumberOfArguments($canon_path_count, $resource['operations']['retrieve'])
&& !empty($canonical_path_array[0])
) {
$operation_type = 'operations';
$operation = 'retrieve';
}
...
}
如果我们现在看一下$this->checkNumberOfArguments()的代码:
// We can see from the snippet above that $args_number = $canon_path_count and hence that
// $args_number is always greater than 0
protected function checkNumberOfArguments($args_number, $resource_operation, $required_args = 0) {
$not_required_args = 0;
if (isset($resource_operation['args'])) {
foreach ($resource_operation['args'] as $argument) {
if (isset($argument['source']) && is_array($argument['source']) && isset($argument['source']['path'])) {
if (!empty($argument['optional'])) {
$not_required_args++;
}
else {
$required_args++;
}
}
}
}
// This is where we fall down; Since the service definition does not include any args,
// both $required_args and $not_required_args will equal zero when we get here. Not a problem
// for the first condition (1 >= 0), but clearly the second condition (1 <= 0 + 0) will evaluate
// to false and hence the argument count will not be accepted. As a result, the services module
// does not accept this controller and reports this as '404 not found'
return $args_number >= $required_args && $args_number <= $required_args + $not_required_args;
}
尝试在服务定义中添加一个参数,如下所示:
<?php
/**
* Implements of hook_services_resources().
*/
function mohtadoon_api_services_resources() {
$api = array(
'mohtadoon' => array(
'operations' => array(
'retrieve' => array(
'help' => 'Retrieves mohtadoon data',
'callback' => 'mohtadoon_api_stories_retrieve',
'file' => array('file' => 'inc', 'module' => 'mohtadoon_api','name' => 'resources/mohtadoon_api'),
'access arguments' => array('access content'),
'arg' => array(
array(
'name' => 'entity',
'type' => 'string',
'description' => 'Entity to operate on',
'source' => array('path' => '0'),
'optional' => TRUE,
'default' => '0',
),
),
),
),
),
);
return $api;
}
编辑:
我认为,阅读你链接的博客文章(我就是其中之一!)的人感到困惑的是,作为服务访问器提供的URL包含了它要调用的方法的名称("检索")作为其最终参数。您可以用几乎任何东西替换"retrieve",服务仍然应该响应(例如"/api/blog/ppink-rabbit",或者在您的情况下,"api/mohtadoon/ppink-rabbit")。web服务定义本身并不指示可以向端点传递哪些参数值。重要的是使用什么HTTP方法访问服务,以及向端点传递了多少参数(零个或更多)。某些类型的操作至少需要一定数量的参数(例如,"检索"操作至少需要一个参数来识别要检索的特定内容)。