Drupal服务端点返回404:找不到资源检索



我遵循了本教程: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未找到:找不到资源检索。

为什么会发生这种情况&amp;如何调试这样的东西。。。我以前没有和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方法访问服务,以及向端点传递了多少参数(零个或更多)。某些类型的操作至少需要一定数量的参数(例如,"检索"操作至少需要一个参数来识别要检索的特定内容)。

最新更新