Restful API naming conventions

32,360

Solution 1

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

Solution 2

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

Solution 3

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 organisation
  • etc.

An 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 organisation

From 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?

Solution 4

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.

  • /users - a list of users
  • /users/1 - user with an ID of 1
  • /users/1/organizations - the orgs that user belongs to
  • /organizations - a list of orgs
  • /organizations/1 - Organization number 1
  • /organizations/1/users - The users for that organization

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:

  • /users?orgId=1

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

Share:
32,360
We0
Author by

We0

I am a dev, I suck at writing about me's, as any dev should. I hate the inability to adapt, whether in code or in business. As a rule, I hate business. There is an exception to every rules, except the rule that there is an exception to every rule. I code in PHP, Java, C# <--These are proper coding languages Technologies I use Javascript (Jquery, AngularJS), CSS, HTML, Bootstrap, Docker, Mysql, Mssql (what I can remember doing lately, probably some more stuff which I forgot about). I am happily employed, but I like discussing ideas. I am part entrepreneur, part crazy and part developer. Part crazy is required for both of those careers.

Updated on July 09, 2022

Comments

  • We0
    We0 almost 2 years

    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/.

  • We0
    We0 almost 10 years
    I can't drop the organisations part because we have /users, /orders etc, but thanks
  • We0
    We0 almost 10 years
    Let me ask it for you this way, if I wanted to delete all the users for an organisation would you recommend DELETE /organisations/{orgId}/users? Somehow in my head I got it that the HTTP action (PUT, POST, DELETE, GET) should relate to the resource...
  • Pharylon
    Pharylon almost 10 years
    Yes. The verb is what you do with the resource. You GET a list of all users at /organisations/{orgId}/users so if you want to DELETE all the users, you use the same address. Both addresses access the same resource(s), but the verb specifies what you do with/to that resource.
  • We0
    We0 almost 10 years
    Yeah, but I am not "GETTING" or "DELETING" organisations, I am "GETTING" users?
  • Sam Holder
    Sam Holder almost 10 years
    you are getting or deleting the users that belong to the organisation
  • We0
    We0 almost 10 years
    And if it was mydomain.com/users/organisation/{orgId} ? I don't care much for what happens after the /user or /organisations, my question rather it whether to follow parent-child-child or relation to resuorce
  • Tim
    Tim almost 10 years
    @We0 i just edited this in: A resource is not necessarily specified in the first part of the url.. So in that case yes you want to do parent/child/child
  • Pharylon
    Pharylon almost 10 years
    Imagine they are parent-child objects. You open the "Organization" box, and find all the "users" inside it and delete them.
  • Tim
    Tim almost 10 years
    @We0 i made a new edit to answer your update
  • We0
    We0 almost 10 years
    It makes sense to me, HTTP action = delete, what am I deleting = user where organisation = id.
  • We0
    We0 almost 10 years
    Sorry if duplicate, but couldn't find anything on it...
  • Sam Holder
    Sam Holder almost 10 years
    then would DELETE mydomain.com/organisation/{orgId}/users delete users or organisations that contain that user?
  • We0
    We0 almost 10 years
    Ok thanks, makes sense
  • inf3rno
    inf3rno almost 10 years
  • Andrew Barber
    Andrew Barber over 9 years
    May I inquire as to the many edits you've done which totally overhaul the answers?
  • inf3rno
    inf3rno over 9 years
    I correct my old answers about REST. I wrote them before reading scientific articles in the topic, so most of them are totally wrong.
  • inf3rno
    inf3rno over 9 years
    Btw. I got about 70 to go (every day 10 is allowed afaik). Should I stop this?
  • Andrew Barber
    Andrew Barber over 9 years
    It's a bit much, yes. Maybe ones like this where there are other answers and you have no votes either way on yours, you could delete instead. And don't do quite so many at a time. Also, don't forget to @-reply so I get notified
  • inf3rno
    inf3rno over 9 years
    @AndrewBarber Ok, I'll delete where I can, but I have 5 deletes/day limit, so that won't be fast either...
  • Andrew Barber
    Andrew Barber over 9 years
    @inf3rno Not a problem at all. :-)
  • ErikE
    ErikE almost 9 years
    And when a user can belong to more than one organization, does this still make sense?
  • Sivaramvt
    Sivaramvt about 6 years
    Totally agree!!