How can I implement a non-CRUD function in hook_service_resources()? This question is similar to this question but I don't understand how the URLs are modified enough for the answer there to make sense to me.

The module adds retrieve and index operations by default.  I am attempting to extend privatemsg_services_resources with an additional option, unread.

I have added unread to the function as shown below, but I cannot figure out how to access it via URL.

function privatemsg_services_services_resources() {
  return array(
    'privatemsg' =&gt; array(
      'operations' =&gt; array(
        'index'    =&gt; array(
          'callback'        =&gt; '_privatemsg_services_get',
          'access callback' =&gt; 'user_is_logged_in',
          'args'            =&gt; array(),
        ),
        'unread'    =&gt; array(
          'callback'        =&gt; '_privatemsg_services_unread_count',
          'access callback' =&gt; 'user_is_logged_in',
            'args' =&gt; array(
              array(
                'name'        =&gt; 'uid',
                'type'        =&gt; 'int',
                'description' =&gt; t('UID of the user to check the number of unread messages for.'),
                'source'      =&gt; array(
                  'path' =&gt; 0,
                ),
              ),
            ),
          ),
        'retrieve' =&gt; array(
          'callback' =&gt; '_privatemsg_services_get_thread',
          'access arguments' =&gt; array(
            'get private messages from remote',
          ),
          'args' =&gt; array(
            array(
              'name'        =&gt; 'thread_id',
              'type'        =&gt; 'int',
              'description' =&gt; t('ID of the thread to be retrieved.'),
              'source'      =&gt; array(
                'path' =&gt; 0,
              ),
            ),
          ),
        ),
      ),
    ),
  );
}


When I go to www.myexample.com/drupalgap/privatemsg, I get the value for index.

When I go to www.myexample.com/drupalgap/privatemsg/THREAD_ID, I get the retrieve value for THREAD_ID.

When I go to www.myexample.com/drupalgap/privatemsg/unread/UID or www.myexample.com/drupalgap/privatemsg/unread, I get the message ["Invalid parameters passed."].

However, if I comment out the function for retrieve and then rename unread to retrieve (to test my code for unread), after clearing the caches, going to  www.myexample.com/drupalgap/privatemsg/UID gives me the number of unread messages.  So the code is OK, I'm just setting up the resource the wrong way.

How can I call both retrieve and unread from the URL?
The key is to use the actions array instead of the operations array when creating non-CRUD resources.

Here's an example for DrupalGap: http://drupalgap.org/node/187

FYI, all calls must use POST when using actions.

When using operations, the calls are directed based on the HTTP method (GET, POST, PUT, DELETE).

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

Since this is for DrupalGap, and you're passing along an argument to your service resource, I'd recommend following these instructions, that way jDrupal can be utilized and your function(s) can easily be re-used:

http://drupalgap.org/node/203