So me and my boss aren't agreeing here and can't find any information on it. Scenario: I want to get all the users for a certain organisation. What should the URL be?
mydomain.com/users/by/organisation/{orgId}
OR
mydomain.com/organisation/{orgId}/users
Our arguments:
Case 1: The call is expected to return "users" and therefore the "resource" (first part of the call) should relate to it.
Case 2: The organisation "owns"/"is the parent of" the user and therefore the organisation should be first.
What are your thoughts?
UPDATE:
I am not to worried about what comes after the mydomain.com/{resource}
. The question relates mostly to whether the HTTP action (GET, POST, PUT, DELETE) should relate to the first resource mydomain.com/users
or whether it should reflect the relationship mydomain.com/organisations/users/
.
REST APIs are typically structured in a hierarchy: for example, https://api.example.com/users/123/first-name will retrieve the first name of the user with ID number 123. The forward slash (“/”) character should be used to navigate this hierarchy, moving from general to specific when going from left to right in the URI.
Names used in APIs should be in correct American English. For example, license (instead of licence), color (instead of colour). Commonly accepted short forms or abbreviations of long words may be used for brevity. For example, API is preferred over Application Programming Interface.
The standard best practice for REST APIs is to have a hyphen, not camelcase or underscores.
Plural Nouns Are Preferable, Rather Than Singular Using plural or singular nouns for defining resources has no any impact on how your API will work; however, there are common conventions that are used in all good RESTful APIs. One of such conventions is the use of plural nouns for defining resources.
You are probably aware that REST has no strict rules, you are more or less free to implement it however you like, but here are my 2 cents
mydomain.com/users/by/organisation/{orgId}
However this sounds like a good url because it sort of tells you what it does by reading it, this is not a great idea. Normally, each url segment specifies a resource that exists or can exist.
In this case, users
represents one or more resources and so does organisation
, but by
does not, it's probably nothing more than a word to help clarify what the API does.
The call is expected to return "users" and therefore the "resource" (first part of the call) should relate to it.
A resource is not necessarily specified in the first part of the url. It can be the 2nd, 3rd or 10th if you want
mydomain.com/organisation/{orgId}/users
This looks much better but I think there is 1 point of improvement. You should rename organisation
to organisations
, to match users
This
mydomain.com/organisations/{orgId}
then gets the organisation with id orgId
, and
mydomain.com/organisations/{orgId}/users
gets all the users that belong to that organisation.
To further narrow it down you could do
mydomain.com/organisations/{orgId}/users/{userId}
to get one specific user belonging to one specific organisation
UPDATE: I am not to worried about what comes after the mydomain.com/{resource}. The question relates mostly to whether the HTTP action (GET, POST, PUT, DELETE) should relate to the first resource mydomain.com/users or whether it should reflect the relationship mydomain.com/organisations/users/.
To answer your update:
I already mentioned it above; A resource is not necessarily specified in the first part of the url.. If the quality of the url improves by shifting the wanted resource to the back of the url, go ahead and do so
There is a conceptual difference between what you are trying to show here. The first is a filtering of all the user resources in the system based on some criteria. The second is showing the user resources that belong to an organisation.
The second url is ok for showing users that belong to an organisation I think.
The first url is effectively filtering the users that you want to see from all users.
Using the url might be ok for the filtering, though using url querystring is also be ok. so
mydomain.com/users?organisationId={orgId}
might be preferable. The urls can still contain querystrings and be restful.
Does it really make any sense to DELETE mydomain.com/users/organisation/{orgid}
? Would you expect that to delete the organisation? if not then this isn't really pointing at a resource and so you are doing a search, and should probably use querystrings.
There are other options for doing the search like making the search criteria a first class object, or using one of the other filtering techniques in this question or this question
Let me start with this: technically, it shouldn't really matter. REST states that URL's must be discoverable through links, like links in normal (HTML) web pages.
However, a consistent, self-explanatory URL-structure won't harm at all. I'd suggest a hierarchical structure in URLs:
/organisations
returns a list of all organisations/organisations/123
returns a specific organisation (#123)/organisations/123/users
returns a list of users that are associated to that organisationAn alternative would be using a query string for filtering:
/users
returns a list of all users/users?organisation=123
returns a list of users that are associated to that organisationFrom this hierarchical perspective, /users/by/organisation/123
wouldn't make much sense. What would be the result of calling /users/by/organisation
? Or /users/by
?
mydomain.com/users/by/organisation/{orgId}
What does "by" mean? That has no relationship to anything. Try to keep random words out of the URL.
Case 1: The call is expected to return "users" and therefore the "resource" (first part of the call) should relate to it.
That is not a rule that RESTful APIs enforce or expect. It is really not that common in the industry either, and I have worked with a LOOOT of APIs. Consider it to be a folder.
You are look at it like a programmer, like it is SOAP or a PHP function, trying to make getUsersByOrganization($orgId)
and that is not how REST works. :)
IF you have to stick to case 1 (first URI segment = return type) then do this:
That is perfectly RESTful and it is essentially just a filter. You could even do both, but I wouldn't. It is a relationship which has no place there. I try and keep filters to things like: ?active=true
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With