1

I have a service endpoint defined in a custom module, as well as a custom resource. They both appear in the Services admin pages, with the resource and its operation checked.

When I hit http://localhost/myservice/myresource?myparm=1, I do not make it to the callback for the resource, but do not receive an error message. The log output shows:

Location    http://localhost/myservice/myresource?myparam=1
Message 
Server info main object:

stdClass Object
(
    [module] => rest_server
    [endpoint] => myservice
    [endpoint_path] => myservice
    [debug] => 1
    [settings] => Array
    (
    )

)

Which seems to indicate that it is only recognizing the endpoint and not the resource portion of the path.

The defining code is as follows:

function my_feed_ctools_plugin_api($owner, $api) {
  if ($owner == 'services' && $api == 'services') {
    return array(
      'version' => 3,
      'file' => 'my_feed.services.inc', // Optional parameter to indicate the file name to load.
      'path' => drupal_get_path('module', 'my_feed'),
    );
  }
}

function my_feed_services_resources() {
  $my_resource = array(
    'myresource' => array(
      'retrieve' => array(
        'file' => array('type' => 'inc', 'module' => 'my_feed', 'name' => 'my_feed.services'),
        'callback' => '_myresource_retrieve',
        'help' => 'Lorem ipsum.',
        'args' => array(
          array(
            'name' => 'myparm',
            'optional' => TRUE,
            'source' => array('param'),
            'type' => 'string',
            'description' => 'Lorem ipsum',
          ),
        ),
      ),
    ),
  );

  return $my_resource;
}

function my_feed_default_services_endpoint() {
    $endpoint = new stdClass();
    $endpoint->disabled = FALSE;
    $endpoint->api_version = 3;
    $endpoint->name = 'myservice';
    $endpoint->server = 'rest_server';
    $endpoint->path = 'myservice';
    $endpoint->authentication = array();
    $endpoint->server_settings = array();
    $endpoint->resources = array(
      'myresource' => array(
        'operations' => array(
          'retrieve' => array(
            'enabled' => '1',
          ),
        ),
      ),
    );
    $endpoint->debug = 1;

    return array($endpoint);
  }

and in my_feed.services.inc

function _myresource_retrieve($args) {
  print "args=" . print_r($args,1);
}
  • This answer should be useful: drupal.stackexchange.com/a/147699/10645 – tyler.frankenstein Jun 4 '15 at 20:57
  • I found it a bit confusing. It says to follow it's suggestion when using a non-CRUD resource...but the resource isn't CRUD or non-CRUD, it's something like node, comment, or the one I've created. The operation is CRUD or not, and in this case, since the operation is Retrieve, that is CRUD, isn't it? – JAyenGreen Jun 4 '15 at 23:33
  • Unless what you are retrieving is a custom entity type, then no AFAIK. Many, many times I've had to use the actions wrapper and a POST to do a custom "retrieve" with Services. – tyler.frankenstein Jun 5 '15 at 13:09
  • Just to clarify, because I'm not certain whether you mean a custom entity type as opposed to a core entity-type, or a custom entity type as opposed to not an entity at all, I'm using this to return output from nodes, but several different bundles with custom filtering options, so in a way, as a way of requesting the output of a View, were Views being used. In this case, an action? – JAyenGreen Jun 5 '15 at 13:57
  • Yes, I mean a custom entity type (as in a non-core entity type), that's when you implement an entire set of Service resources for CRUD (or use the Services Entity API module). But in your case, when just dealing with nodes, again I recommend using an action and a POST to "retrieve" what you need, unless you can build a View to do it (then use Views Datasource [ala Views JSON] or the Services Views module). – tyler.frankenstein Jun 5 '15 at 14:38
2

You need to wrap your retrieve resource in an actions array:

function my_feed_services_resources() {

  $my_resource = array(
    'myresource' => array(
      'actions' => array(
        'retrieve' => array(
          'file' => array('type' => 'inc', 'module' => 'my_feed', 'name' => 'my_feed.services'),
          'callback' => '_myresource_retrieve',
          'help' => 'Lorem ipsum.',
          'args' => array(
            array(
              'name' => 'myparm',
              'optional' => TRUE,
              'source' => array('param'),
              'type' => 'string',
              'description' => 'Lorem ipsum',
            ),
          ),
        ),
      ),
    ),
  );

  return $my_resource;
}

You can then "fire" it by doing a POST to: ?q=[my-endpoint]/myresource/retrieve.json

Don't forget to attach the X-CSRF-Token header to your POST calls. Its value can be retrieved here: ?q=services/session/token

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.