If I want an operation of GET api/v1.0/users and api/v1.0/pages:

Using the Services module to create a REST API, if I define a service with an endpoint of api/v1.0/users and enable the user resource (let's say I enable the Retrieve action), then I have to go to the URI /api/v1.0/users/user/ to get it to work. If I don't include the /user at the end, it returns a 404 error.

However, if I make the endpoint simply api/v1.0, and enable the same resources, then the URI is closer to expect and want: /api/v1.0/user/, but still not quite right. Also, If I define other endpoints using this style (eg. for /api/v1.0/node/), only the last one works; the rest return a 404 error.

Why is it designed this way? And how can I make it not append the resource name to the end?

Update: Based on @mradcliffe's answer, it seems that it's been designed this way so that you can define a single endpoint as a sort of 'endpoint base', such as api/v1.0, then enable multiple resources, which then append their names to the endpoint path.

The problem I see with that is that, if I later create a new version of a resource (eg. the user resource) that does things a little differently, and I thus want to name it with a new version number (eg. users_1.1) to distinguish it from the old resource, that would create a horrible endpoint path of api/v1.1/users_1.1...?

Update: To answer the question of my previous update, I think a better (more efficient) programming practice would be to simply check the api version within the code (wherever the new code deviates from the old) rather than re-naming the resource. I could define a function that pulls the version out of the path for this checking.

  • 1
    I think that this question is very subjective. Services is designed to create one or more unique endpoints where each endpoint is a collection of resources. This is the way it works. If you want an endpoint for your v1.0 API, then you make it /api/1.0 and enable the node and user resources. If you want an endpoint for your v1.1 API, then you create a new endpoint /api/1.1 and enable the node and user resources. Perhaps it is unclear what you are asking? Why do you want an endpoint that is /api/v1.0/users specifically? – mradcliffe Feb 12 '16 at 16:48
  • Thank you @mradcliffe, you've actually answered my question here in your comment; "why is it done this way"? I was confusing the concept of an enpoint. If you make it an answer, I will vote this one as correct, since it answers my main question. – Dane Rossenrode Feb 13 '16 at 4:32

See mradcliffe's comment for a good explanation of the difference between an endpoint and a resource, understanding that will make it clear why the Services module does things the way it does.

Why is the endpoint for the user entity type specifically named user?

Conceptually speaking it's a safe bet that the module developer followed common REST patterns, and adopted the name of the entity as defined by the system the code is sitting in (i.e. the user entity type defined by Drupal core).

From a technical point of view, the resource is named user because the services module explicitly names it as such in _user_resource_definition():

$definition = array(
    'user' => array(
      'operations' => array(

Not a fan of this particular convention? Not a problem, Services has you covered.

Go to the "Edit Resources" tab for your endpoint, and look in the right hand column of the table; you'll see a text field that takes an "Alias". Set that to "users" for the User resource.

Set your endpoint to something sensible like 'api/v1.0', and you can now access the user resource through its alias at http://example.com/api/v1.0/users. It sounds like you might also want to add a "pages" alias for the "Node" resource, but I'm speculating a bit.

| improve this answer | |

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