What are best practices for REST nested resources?











up vote
210
down vote

favorite
71












As far as I can tell each individual resource should have only one canonical path. So in the following example what would good URL patterns be?



Take for an example a rest representation of Companies. In this hypothetical example, each company owns 0 or more departments and each department owns 0 or more employees.



A department can't exist without an associated company.



An employee can't exist without an associated department.



Now I'd find the natural representation of the resource patterns to be.





  • /companies A collection of companies - Accepts put for a new company. Get for the entire collection.


  • /companies/{companyId} An individual company. Accepts GET, PUT and DELETE


  • /companies/{companyId}/departments Accepts POST for a new item. (Creates a department within the company.)

  • /companies/{companyId}/departments/{departmentId}/

  • /companies/{companyId}/departments/{departmentId}/employees

  • /companies/{companyId}/departments/{departmentId}/employees/{empId}


Given the constraints, in each of the sections, I feel that this makes sense if a bit deeply nested.



However, my difficulty comes if I want to list (GET) all employees across all companies.



The resource pattern for that would most closely map to /employees (The collection of all employees)



Does that mean that I should have /employees/{empId} also because if so then there are two URI's to get the same resource?



Or maybe the entire schema should be flattened but that would mean that employees are a nested top-level object.



At a basic level /employees/?company={companyId}&department={deptId} returns the exact same view of employees as the most deeply nested pattern.



What's the best practice for URL patterns where resources are owned by other resources but should be query-able separately?





UPDATE: See my answer below to see what I've done.










share|improve this question




















  • 1




    This is almost exactly the oppsite problem to that described in stackoverflow.com/questions/7104578/… though the answers may be related. Both questions are about ownership but that example implies that the top level object isn't the owning one.
    – Wes
    Jan 6 '14 at 13:55






  • 1




    Exactly what I was wondering about. For the given use case your solution seems fine, but what if the relation is an aggregation rather than a composition? Still struggling to figure out what the best practice is here... Also, does this solution imply only the creation of the relationship, e.g. an existing person is employed or does it create a person object?
    – Jakob O.
    Mar 28 '14 at 10:32










  • It creates a person in my fictitious example. The reason I used those domain terms is its a reasonably understandable example, though mimicking my actual problem. Have you looked through the linked question that may halp you more for an aggragation relationship.
    – Wes
    Apr 8 '14 at 13:05










  • I've split my question into an answer and a question.
    – Wes
    Sep 28 '15 at 10:30










  • I'm voting to close this question as off-topic because its about a pattern rather than a programming problem and has gathered too many votes.
    – Wes
    Oct 26 '17 at 23:15















up vote
210
down vote

favorite
71












As far as I can tell each individual resource should have only one canonical path. So in the following example what would good URL patterns be?



Take for an example a rest representation of Companies. In this hypothetical example, each company owns 0 or more departments and each department owns 0 or more employees.



A department can't exist without an associated company.



An employee can't exist without an associated department.



Now I'd find the natural representation of the resource patterns to be.





  • /companies A collection of companies - Accepts put for a new company. Get for the entire collection.


  • /companies/{companyId} An individual company. Accepts GET, PUT and DELETE


  • /companies/{companyId}/departments Accepts POST for a new item. (Creates a department within the company.)

  • /companies/{companyId}/departments/{departmentId}/

  • /companies/{companyId}/departments/{departmentId}/employees

  • /companies/{companyId}/departments/{departmentId}/employees/{empId}


Given the constraints, in each of the sections, I feel that this makes sense if a bit deeply nested.



However, my difficulty comes if I want to list (GET) all employees across all companies.



The resource pattern for that would most closely map to /employees (The collection of all employees)



Does that mean that I should have /employees/{empId} also because if so then there are two URI's to get the same resource?



Or maybe the entire schema should be flattened but that would mean that employees are a nested top-level object.



At a basic level /employees/?company={companyId}&department={deptId} returns the exact same view of employees as the most deeply nested pattern.



What's the best practice for URL patterns where resources are owned by other resources but should be query-able separately?





UPDATE: See my answer below to see what I've done.










share|improve this question




















  • 1




    This is almost exactly the oppsite problem to that described in stackoverflow.com/questions/7104578/… though the answers may be related. Both questions are about ownership but that example implies that the top level object isn't the owning one.
    – Wes
    Jan 6 '14 at 13:55






  • 1




    Exactly what I was wondering about. For the given use case your solution seems fine, but what if the relation is an aggregation rather than a composition? Still struggling to figure out what the best practice is here... Also, does this solution imply only the creation of the relationship, e.g. an existing person is employed or does it create a person object?
    – Jakob O.
    Mar 28 '14 at 10:32










  • It creates a person in my fictitious example. The reason I used those domain terms is its a reasonably understandable example, though mimicking my actual problem. Have you looked through the linked question that may halp you more for an aggragation relationship.
    – Wes
    Apr 8 '14 at 13:05










  • I've split my question into an answer and a question.
    – Wes
    Sep 28 '15 at 10:30










  • I'm voting to close this question as off-topic because its about a pattern rather than a programming problem and has gathered too many votes.
    – Wes
    Oct 26 '17 at 23:15













up vote
210
down vote

favorite
71









up vote
210
down vote

favorite
71






71





As far as I can tell each individual resource should have only one canonical path. So in the following example what would good URL patterns be?



Take for an example a rest representation of Companies. In this hypothetical example, each company owns 0 or more departments and each department owns 0 or more employees.



A department can't exist without an associated company.



An employee can't exist without an associated department.



Now I'd find the natural representation of the resource patterns to be.





  • /companies A collection of companies - Accepts put for a new company. Get for the entire collection.


  • /companies/{companyId} An individual company. Accepts GET, PUT and DELETE


  • /companies/{companyId}/departments Accepts POST for a new item. (Creates a department within the company.)

  • /companies/{companyId}/departments/{departmentId}/

  • /companies/{companyId}/departments/{departmentId}/employees

  • /companies/{companyId}/departments/{departmentId}/employees/{empId}


Given the constraints, in each of the sections, I feel that this makes sense if a bit deeply nested.



However, my difficulty comes if I want to list (GET) all employees across all companies.



The resource pattern for that would most closely map to /employees (The collection of all employees)



Does that mean that I should have /employees/{empId} also because if so then there are two URI's to get the same resource?



Or maybe the entire schema should be flattened but that would mean that employees are a nested top-level object.



At a basic level /employees/?company={companyId}&department={deptId} returns the exact same view of employees as the most deeply nested pattern.



What's the best practice for URL patterns where resources are owned by other resources but should be query-able separately?





UPDATE: See my answer below to see what I've done.










share|improve this question















As far as I can tell each individual resource should have only one canonical path. So in the following example what would good URL patterns be?



Take for an example a rest representation of Companies. In this hypothetical example, each company owns 0 or more departments and each department owns 0 or more employees.



A department can't exist without an associated company.



An employee can't exist without an associated department.



Now I'd find the natural representation of the resource patterns to be.





  • /companies A collection of companies - Accepts put for a new company. Get for the entire collection.


  • /companies/{companyId} An individual company. Accepts GET, PUT and DELETE


  • /companies/{companyId}/departments Accepts POST for a new item. (Creates a department within the company.)

  • /companies/{companyId}/departments/{departmentId}/

  • /companies/{companyId}/departments/{departmentId}/employees

  • /companies/{companyId}/departments/{departmentId}/employees/{empId}


Given the constraints, in each of the sections, I feel that this makes sense if a bit deeply nested.



However, my difficulty comes if I want to list (GET) all employees across all companies.



The resource pattern for that would most closely map to /employees (The collection of all employees)



Does that mean that I should have /employees/{empId} also because if so then there are two URI's to get the same resource?



Or maybe the entire schema should be flattened but that would mean that employees are a nested top-level object.



At a basic level /employees/?company={companyId}&department={deptId} returns the exact same view of employees as the most deeply nested pattern.



What's the best practice for URL patterns where resources are owned by other resources but should be query-able separately?





UPDATE: See my answer below to see what I've done.







rest api-design






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 8 at 11:20

























asked Jan 6 '14 at 13:51









Wes

2,48422350




2,48422350








  • 1




    This is almost exactly the oppsite problem to that described in stackoverflow.com/questions/7104578/… though the answers may be related. Both questions are about ownership but that example implies that the top level object isn't the owning one.
    – Wes
    Jan 6 '14 at 13:55






  • 1




    Exactly what I was wondering about. For the given use case your solution seems fine, but what if the relation is an aggregation rather than a composition? Still struggling to figure out what the best practice is here... Also, does this solution imply only the creation of the relationship, e.g. an existing person is employed or does it create a person object?
    – Jakob O.
    Mar 28 '14 at 10:32










  • It creates a person in my fictitious example. The reason I used those domain terms is its a reasonably understandable example, though mimicking my actual problem. Have you looked through the linked question that may halp you more for an aggragation relationship.
    – Wes
    Apr 8 '14 at 13:05










  • I've split my question into an answer and a question.
    – Wes
    Sep 28 '15 at 10:30










  • I'm voting to close this question as off-topic because its about a pattern rather than a programming problem and has gathered too many votes.
    – Wes
    Oct 26 '17 at 23:15














  • 1




    This is almost exactly the oppsite problem to that described in stackoverflow.com/questions/7104578/… though the answers may be related. Both questions are about ownership but that example implies that the top level object isn't the owning one.
    – Wes
    Jan 6 '14 at 13:55






  • 1




    Exactly what I was wondering about. For the given use case your solution seems fine, but what if the relation is an aggregation rather than a composition? Still struggling to figure out what the best practice is here... Also, does this solution imply only the creation of the relationship, e.g. an existing person is employed or does it create a person object?
    – Jakob O.
    Mar 28 '14 at 10:32










  • It creates a person in my fictitious example. The reason I used those domain terms is its a reasonably understandable example, though mimicking my actual problem. Have you looked through the linked question that may halp you more for an aggragation relationship.
    – Wes
    Apr 8 '14 at 13:05










  • I've split my question into an answer and a question.
    – Wes
    Sep 28 '15 at 10:30










  • I'm voting to close this question as off-topic because its about a pattern rather than a programming problem and has gathered too many votes.
    – Wes
    Oct 26 '17 at 23:15








1




1




This is almost exactly the oppsite problem to that described in stackoverflow.com/questions/7104578/… though the answers may be related. Both questions are about ownership but that example implies that the top level object isn't the owning one.
– Wes
Jan 6 '14 at 13:55




This is almost exactly the oppsite problem to that described in stackoverflow.com/questions/7104578/… though the answers may be related. Both questions are about ownership but that example implies that the top level object isn't the owning one.
– Wes
Jan 6 '14 at 13:55




1




1




Exactly what I was wondering about. For the given use case your solution seems fine, but what if the relation is an aggregation rather than a composition? Still struggling to figure out what the best practice is here... Also, does this solution imply only the creation of the relationship, e.g. an existing person is employed or does it create a person object?
– Jakob O.
Mar 28 '14 at 10:32




Exactly what I was wondering about. For the given use case your solution seems fine, but what if the relation is an aggregation rather than a composition? Still struggling to figure out what the best practice is here... Also, does this solution imply only the creation of the relationship, e.g. an existing person is employed or does it create a person object?
– Jakob O.
Mar 28 '14 at 10:32












It creates a person in my fictitious example. The reason I used those domain terms is its a reasonably understandable example, though mimicking my actual problem. Have you looked through the linked question that may halp you more for an aggragation relationship.
– Wes
Apr 8 '14 at 13:05




It creates a person in my fictitious example. The reason I used those domain terms is its a reasonably understandable example, though mimicking my actual problem. Have you looked through the linked question that may halp you more for an aggragation relationship.
– Wes
Apr 8 '14 at 13:05












I've split my question into an answer and a question.
– Wes
Sep 28 '15 at 10:30




I've split my question into an answer and a question.
– Wes
Sep 28 '15 at 10:30












I'm voting to close this question as off-topic because its about a pattern rather than a programming problem and has gathered too many votes.
– Wes
Oct 26 '17 at 23:15




I'm voting to close this question as off-topic because its about a pattern rather than a programming problem and has gathered too many votes.
– Wes
Oct 26 '17 at 23:15












6 Answers
6






active

oldest

votes

















up vote
105
down vote



accepted










What you have done is correct. In general there can be many URIs to the same resource - there are no rules that say you shouldn't do that.



And generally, you may need to access items directly or as a subset of something else - so your structure makes sense to me.



Just because employees are accessible under department:



company/{companyid}/department/{departmentid}/employees



Doesn't mean they can't be accessible under company too:



company/{companyid}/employees



Which would return employees for that company. It depends on what is needed by your consuming client - that is what you should be designing for.



But I would hope that all URLs handlers use the same backing code to satisfy the requests so that you aren't duplicating code.






share|improve this answer



















  • 9




    This is pointing out the spirit of RESTful, there are no rules that say you should or should not do if only you consider a meaningful resource first. But further, I wonder what's the best practice for not duplicating code in such scenarios.
    – abookyun
    May 13 '15 at 3:18








  • 9




    @abookyun if you need both routes, then repeated controller code between them can be abstracted to service objects.
    – bgcode
    Dec 3 '15 at 20:37










  • This has nothing to do with REST. REST does not care about how you structure the path part of your URLs... all it cares about is valid, hopefully durable URIs...
    – redben
    Apr 5 '16 at 14:51










  • Driving at this answer, I think any api where the dynamic segments are all unique identifiers shouldn't need to handle multiple dynamic segments (/company/3/department/2/employees/1). If the api provides ways to get each resource, then making each of those requests could be done in either a client side library or as a one-off endpoint that reuses code.
    – max
    Jul 3 '16 at 5:02












  • While there is no prohibition, I consider it more elegant to have only one path to a resource - keeps all mental models simpler. I also prefer that URIs don't change their resource type if there is any nesting. for example /company/* should only return the company resource and not change resource type at all. None of this is specified by REST - its generally a poorly specified - just personal preference.
    – kashif
    Oct 2 '17 at 3:57




















up vote
103
down vote













I've tried both design strategies - nested and non-nested endpoints. I've found that:




  1. if the nested resource has a primary key and you don't have its parent primary key, the nested structure requires you to get it, even though the system doesn't actually require it.


  2. nested endpoints typically require redundant endpoints. In other words, you will more often than not, need the additional /employees endpoint so you can get a list of employees across departments. If you have /employees, what exactly does /companies/departments/employees buy you?


  3. nesting endpoints don't evolve as nicely. E.g. you might not need to search for employees now but you might later and if you have a nested structure, you have no choice but to add another endpoint. With a non-nested design, you just add more parameters, which is simpler.


  4. sometimes a resource could have multiple types of parents. Resulting in multiple endpoints all returning the same resource.


  5. redundant endpoints makes the docs harder to write and also makes the api harder to learn.



In short, the non-nested design seems to allow a more flexible and simpler endpoint schema.






share|improve this answer

















  • 11




    Was very refreshing to come across this answer. I have been using nested endpoints for several months now after being taught that was the "right way". I came to all of the same conclusions you listed above. So much easier with a non-nested design.
    – user3344977
    Apr 20 '17 at 16:16












  • Would it also mean that primary key should be delivered a parameter of a query string instead of being delivered as a part of main url. /Employees?id=500, instead of /Employees/500. Wouldn't that also scale better in case you also require a primary key from a parent resource?
    – mko
    Nov 6 '17 at 12:32






  • 3




    You seem to list some of the downsides as upsides. "Just cram more parameters into a single end-point" makes the API harder to document and learn, not the other way around. ;-)
    – Drenmi
    Nov 21 '17 at 17:21






  • 3




    Not a fan of this answer. There's no need to introduce redundant endpoints just because you've added a nested resource. It's also not a problem to have the same resource returned by multiple parents, provided those parents genuinely own the nested resource. It's not a problem to get a parent resource to learn how to interact with the nested resources. A good discoverable REST API should do this.
    – Scottm
    Dec 11 '17 at 9:27






  • 1




    @Scottm - One drawback of nested resources that I came across is that it could lead to returning incorrect data if the parent resource ids are incorrect/mismatch. Assuming there are no authorization issues, it is left upto the api implementation to verify that the nested resource is indeed a child of the parent resource that is passed. If this check is not coded for, the api response could be incorrect leading to corruption. What are your thoughts?
    – Andy Dufresne
    Jul 12 at 14:40


















up vote
53
down vote













I've moved what I've done from the question to an answer where more people are likely to see it.



What I've done is to have the creation endpoints at the nested endpoint, The canonical endpoint for modifying or querying an item is not at the nested resource.



So in this example (just listing the endpoints that change a resource)





  • POST /companies/ creates a new company returns a link to the created company.


  • POST /companies/{companyId}/departments when a department is put creates the new department returns a link to /departments/{departmentId}


  • PUT /departments/{departmentId} modifies a department


  • POST /departments/{deparmentId}/employees creates a new employee returns a link to /employees/{employeeId}


So there are root level resources for each of the collections. However the create is in the owning object.






share|improve this answer



















  • 2




    I have come up with the same type of design as well. I think it's intuitive to create things like this "where they belong", but then still be able to list them globally. Even more so when there's a relationship where a resource MUST have a parent. Then creating that resource globally does not make that obvious, but doing it in a sub-resource like this makes perfect sense.
    – Joakim
    Sep 11 '16 at 20:27










  • I guess you used POST meaning PUT, and otherwise.
    – Gerardo Lima
    Jan 18 at 15:43










  • Actually no Note that I'm not using pre assigned Ids for creation as the server in this case is responsible for returning the id (in the link). Therefore writing POST is correct (can't do a get on the same implementation). The put however changes the entire resource but its still available at the same location so I PUT it. PUT vs POST is a different matter and is controversial too. For example stackoverflow.com/questions/630453/put-vs-post-in-rest
    – Wes
    Jan 18 at 16:57












  • @Wes Even I prefer modifying verb methods to be under the parent. But, do you see passing query parameter for global resource is accepted well? Ex : POST /departments with query parameter company=company-id
    – Ayyappa
    Apr 9 at 12:48












  • @Ayyappa Its not something I would personally do, but I woudn't be too shocked if it did happen. Normally I don't like mixing query strings with posted bodies. But I have done it in the past many years ago.
    – Wes
    Apr 11 at 8:03


















up vote
6
down vote













I disagree with this kind of path



GET /companies/{companyId}/departments


If you want to get departments, I think it's better to use a /departments resource



GET /departments?companyId=123


I suppose you have a companies table and a departments table then classes to map them in the programming language you use. I also assume that departments could be attached to other entities than companies, so a /departments resource is straightforward, it's convenient to have resources mapped to tables and also you don't need as many endpoints since you can reuse



GET /departments?companyId=123


for any kind of search, for instance



GET /departments?name=xxx
GET /departments?companyId=123&name=xxx
etc.


If you want to create a department, the



POST /departments


resource should be used and the request body should contain the company ID (if the department can be linked to only one company).






share|improve this answer























  • To me, this is an acceptable approach only if the nested object makes sense as an atomic object. If they are not, It wouldnt really make sense to break them apart.
    – Simon Aronsson
    Sep 26 '16 at 10:26










  • This is what I said, if you also want to be able to retrieve departments, meaning if you'll use a /departments endpoint.
    – Maxime Laval
    Sep 26 '16 at 17:21






  • 2




    It may also make sense to allow departments to be included via lazy loading when fetching a company, eg GET /companies/{companyId}?include=departments, since this allows both the company and its departments to be fetched in a single HTTP request. Fractal does this really well.
    – Matthew Daly
    Jul 27 '17 at 11:31










  • When you're setting up acls you probably want to restrict the /departments endpoint to only be accessible by an admin, and have each company access their own departments only through ` /companies/{companyId}/departments`
    – Cuzox
    Dec 26 '17 at 13:34










  • @MatthewDaly OData also does that nicely with $expand
    – Robert Grant
    Jan 2 at 10:37


















up vote
6
down vote













How your URLs look have nothing to do with REST. Anything goes. It actually is an "implementation detail". So just like how you name your variables. All they have to be is unique and durable.



Don't waste too much time on this, just make a choice and stick to it/be consistent. For example if you go with hierarchies then you do it for all your resources. If you go with query parameters...etc just like naming conventions in your code.



Why so ? As far as I know a "RESTful" API is to be browsable (you know..."Hypermedia as the Engine of Application State"), therefore an API client does not care about what your URLs are like as long as they're valid (there's no SEO, no human that needs to read those "friendly urls", except may be for debugging...)



How nice/understandable a URL is in a REST API is only interesting to you as the API developer, not the API client, as would the name of a variable in your code be.



The most important thing is that your API client know how to interpret your media type.
For example it knows that :




  • your media type has a links property that lists available/related links.

  • Each link is identified by a relationship (just like browsers know that link[rel="stylesheet"] means its a style sheet or rel=favico is a link to a favicon...)

  • and it knowns what those relationships mean ("companies" mean a list of companies,"search" means a templated url for doing a search on a list of resource, "departments" means departments of the current resource )


Below is an example HTTP exchange (bodies are in yaml since it's easier to write):



Request



GET / HTTP/1.1
Host: api.acme.io
Accept: text/yaml, text/acme-mediatype+yaml


Response: a list of links to main resource (companies, people, whatever...)



HTTP/1.1 200 OK
Date: Tue, 05 Apr 2016 15:04:00 GMT
Last-Modified: Tue, 05 Apr 2016 00:00:00 GMT
Content-Type: text/acme-mediatype+yaml

# body: this is your API's entrypoint (like a homepage)
links:
# could be some random path https://api.acme.local/modskmklmkdsml
# the only thing the API client cares about is the key (or rel) "companies"
companies: https://api.acme.local/companies
people: https://api.acme.local/people


Request: link to companies (using previous response's body.links.companies)



GET /companies HTTP/1.1
Host: api.acme.local
Accept: text/yaml, text/acme-mediatype+yaml


Response: a partial list of companies (under items), the resource contains related links, like link to get the next couple of companies (body.links.next) an other (templated) link to search (body.links.search)



HTTP/1.1 200 OK
Date: Tue, 05 Apr 2016 15:06:00 GMT
Last-Modified: Tue, 05 Apr 2016 00:00:00 GMT
Content-Type: text/acme-mediatype+yaml

# body: representation of a list of companies
links:
# link to the next page
next: https://api.acme.local/companies?page=2
# templated link for search
search: https://api.acme.local/companies?query={query}
# you could provide available actions related to this resource
actions:
add:
href: https://api.acme.local/companies
method: POST
items:
- name: company1
links:
self: https://api.acme.local/companies/8er13eo
# and here is the link to departments
# again the client only cares about the key department
department: https://api.acme.local/companies/8er13eo/departments
- name: company2
links:
self: https://api.acme.local/companies/9r13d4l
# or could be in some other location !
department: https://api2.acme.local/departments?company=8er13eo


So as you see if you go the links/relations way how you structure the path part of your URLs does't have any value to your API client. And if your are communicating the structure of your URLs to your client as documentation, then your are not doing REST (or at least not Level 3 as per "Richardson's maturity model")






share|improve this answer



















  • 6




    "How nice/understandable a URL is in a REST API is only interesting to you as the API developer, not the API client, as would the name of a variable in your code be." Why would this NOT be interesting? This is very important, if anyone but yourself is also using the API. This is part of the user experience, so I would say it is very important that this is easy to understand for the API client developers. Making things even more easy to understand by linking resources clearly is of course a bonus (level 3 in the url you provide). Everything should be intuitive and logical with clear relations.
    – Joakim
    Sep 11 '16 at 20:33






  • 1




    @Joakim If you are making a level 3 rest API (Hypertext As The Engine Of Application State), then the url's path structure is absolutely of no interest to the client (as long as it is valid). If you are not aiming for level 3, then yes, it is important and should be guessable. But real REST is level 3. A good article: martinfowler.com/articles/richardsonMaturityModel.html
    – redben
    Sep 11 '16 at 21:19






  • 3




    I object to ever creating an API or UI that is not user friendly for human beings. Level 3 or not, I agree linking resources is a great idea. But to suggest doing so "makes it possible to change URL scheme" is to be out of touch with reality, and how people use APIs. So it's a bad recommendation. But sure in the best of all worlds everyone would be at Level 3 REST. I incorporate hyperlinks AND use a humanly understandable URL scheme. Level 3 does not exclude the former, and one SHOULD care in my opinion. Good article though :)
    – Joakim
    Sep 11 '16 at 21:29










  • One should of course care for the sake of maintainability and other concerns, I think you miss the point of my answer : the way the url looks does not deserve a lot of thinking and you should "just make a choice and stick to it/be consistent" as I said in the answer. And in the case of a REST API, at least my opinion, user friendlyness is not in the url, it is mostly in (the media type) Anyway I hope you understand my point :)
    – redben
    Sep 11 '16 at 22:14




















up vote
5
down vote













I've read all of above answer but seem like have no common strategy. I found a good article about best practices in Design API from Microsoft Documents. I think you should refer.




In more complex systems, it can be tempting to provide URIs that
enable a client to navigate through several levels of relationships,
such as /customers/1/orders/99/products. However, this level of
complexity can be difficult to maintain and is inflexible if the
relationships between resources change in the future. Instead, try to
keep URIs relatively simple
. Once an application has a reference to a
resource, it should be possible to use this reference to find items
related to that resource. The preceding query can be replaced with the
URI /customers/1/orders to find all the orders for customer 1, and
then /orders/99/products to find the products in this order.




.




Tip



Avoid requiring resource URIs more complex than
collection/item/collection.







share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f20951419%2fwhat-are-best-practices-for-rest-nested-resources%23new-answer', 'question_page');
    }
    );

    Post as a guest
































    6 Answers
    6






    active

    oldest

    votes








    6 Answers
    6






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    105
    down vote



    accepted










    What you have done is correct. In general there can be many URIs to the same resource - there are no rules that say you shouldn't do that.



    And generally, you may need to access items directly or as a subset of something else - so your structure makes sense to me.



    Just because employees are accessible under department:



    company/{companyid}/department/{departmentid}/employees



    Doesn't mean they can't be accessible under company too:



    company/{companyid}/employees



    Which would return employees for that company. It depends on what is needed by your consuming client - that is what you should be designing for.



    But I would hope that all URLs handlers use the same backing code to satisfy the requests so that you aren't duplicating code.






    share|improve this answer



















    • 9




      This is pointing out the spirit of RESTful, there are no rules that say you should or should not do if only you consider a meaningful resource first. But further, I wonder what's the best practice for not duplicating code in such scenarios.
      – abookyun
      May 13 '15 at 3:18








    • 9




      @abookyun if you need both routes, then repeated controller code between them can be abstracted to service objects.
      – bgcode
      Dec 3 '15 at 20:37










    • This has nothing to do with REST. REST does not care about how you structure the path part of your URLs... all it cares about is valid, hopefully durable URIs...
      – redben
      Apr 5 '16 at 14:51










    • Driving at this answer, I think any api where the dynamic segments are all unique identifiers shouldn't need to handle multiple dynamic segments (/company/3/department/2/employees/1). If the api provides ways to get each resource, then making each of those requests could be done in either a client side library or as a one-off endpoint that reuses code.
      – max
      Jul 3 '16 at 5:02












    • While there is no prohibition, I consider it more elegant to have only one path to a resource - keeps all mental models simpler. I also prefer that URIs don't change their resource type if there is any nesting. for example /company/* should only return the company resource and not change resource type at all. None of this is specified by REST - its generally a poorly specified - just personal preference.
      – kashif
      Oct 2 '17 at 3:57

















    up vote
    105
    down vote



    accepted










    What you have done is correct. In general there can be many URIs to the same resource - there are no rules that say you shouldn't do that.



    And generally, you may need to access items directly or as a subset of something else - so your structure makes sense to me.



    Just because employees are accessible under department:



    company/{companyid}/department/{departmentid}/employees



    Doesn't mean they can't be accessible under company too:



    company/{companyid}/employees



    Which would return employees for that company. It depends on what is needed by your consuming client - that is what you should be designing for.



    But I would hope that all URLs handlers use the same backing code to satisfy the requests so that you aren't duplicating code.






    share|improve this answer



















    • 9




      This is pointing out the spirit of RESTful, there are no rules that say you should or should not do if only you consider a meaningful resource first. But further, I wonder what's the best practice for not duplicating code in such scenarios.
      – abookyun
      May 13 '15 at 3:18








    • 9




      @abookyun if you need both routes, then repeated controller code between them can be abstracted to service objects.
      – bgcode
      Dec 3 '15 at 20:37










    • This has nothing to do with REST. REST does not care about how you structure the path part of your URLs... all it cares about is valid, hopefully durable URIs...
      – redben
      Apr 5 '16 at 14:51










    • Driving at this answer, I think any api where the dynamic segments are all unique identifiers shouldn't need to handle multiple dynamic segments (/company/3/department/2/employees/1). If the api provides ways to get each resource, then making each of those requests could be done in either a client side library or as a one-off endpoint that reuses code.
      – max
      Jul 3 '16 at 5:02












    • While there is no prohibition, I consider it more elegant to have only one path to a resource - keeps all mental models simpler. I also prefer that URIs don't change their resource type if there is any nesting. for example /company/* should only return the company resource and not change resource type at all. None of this is specified by REST - its generally a poorly specified - just personal preference.
      – kashif
      Oct 2 '17 at 3:57















    up vote
    105
    down vote



    accepted







    up vote
    105
    down vote



    accepted






    What you have done is correct. In general there can be many URIs to the same resource - there are no rules that say you shouldn't do that.



    And generally, you may need to access items directly or as a subset of something else - so your structure makes sense to me.



    Just because employees are accessible under department:



    company/{companyid}/department/{departmentid}/employees



    Doesn't mean they can't be accessible under company too:



    company/{companyid}/employees



    Which would return employees for that company. It depends on what is needed by your consuming client - that is what you should be designing for.



    But I would hope that all URLs handlers use the same backing code to satisfy the requests so that you aren't duplicating code.






    share|improve this answer














    What you have done is correct. In general there can be many URIs to the same resource - there are no rules that say you shouldn't do that.



    And generally, you may need to access items directly or as a subset of something else - so your structure makes sense to me.



    Just because employees are accessible under department:



    company/{companyid}/department/{departmentid}/employees



    Doesn't mean they can't be accessible under company too:



    company/{companyid}/employees



    Which would return employees for that company. It depends on what is needed by your consuming client - that is what you should be designing for.



    But I would hope that all URLs handlers use the same backing code to satisfy the requests so that you aren't duplicating code.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Aug 18 '16 at 14:21









    Joakim

    4,93773341




    4,93773341










    answered Oct 15 '14 at 17:11









    jeremyh

    4,27931717




    4,27931717








    • 9




      This is pointing out the spirit of RESTful, there are no rules that say you should or should not do if only you consider a meaningful resource first. But further, I wonder what's the best practice for not duplicating code in such scenarios.
      – abookyun
      May 13 '15 at 3:18








    • 9




      @abookyun if you need both routes, then repeated controller code between them can be abstracted to service objects.
      – bgcode
      Dec 3 '15 at 20:37










    • This has nothing to do with REST. REST does not care about how you structure the path part of your URLs... all it cares about is valid, hopefully durable URIs...
      – redben
      Apr 5 '16 at 14:51










    • Driving at this answer, I think any api where the dynamic segments are all unique identifiers shouldn't need to handle multiple dynamic segments (/company/3/department/2/employees/1). If the api provides ways to get each resource, then making each of those requests could be done in either a client side library or as a one-off endpoint that reuses code.
      – max
      Jul 3 '16 at 5:02












    • While there is no prohibition, I consider it more elegant to have only one path to a resource - keeps all mental models simpler. I also prefer that URIs don't change their resource type if there is any nesting. for example /company/* should only return the company resource and not change resource type at all. None of this is specified by REST - its generally a poorly specified - just personal preference.
      – kashif
      Oct 2 '17 at 3:57
















    • 9




      This is pointing out the spirit of RESTful, there are no rules that say you should or should not do if only you consider a meaningful resource first. But further, I wonder what's the best practice for not duplicating code in such scenarios.
      – abookyun
      May 13 '15 at 3:18








    • 9




      @abookyun if you need both routes, then repeated controller code between them can be abstracted to service objects.
      – bgcode
      Dec 3 '15 at 20:37










    • This has nothing to do with REST. REST does not care about how you structure the path part of your URLs... all it cares about is valid, hopefully durable URIs...
      – redben
      Apr 5 '16 at 14:51










    • Driving at this answer, I think any api where the dynamic segments are all unique identifiers shouldn't need to handle multiple dynamic segments (/company/3/department/2/employees/1). If the api provides ways to get each resource, then making each of those requests could be done in either a client side library or as a one-off endpoint that reuses code.
      – max
      Jul 3 '16 at 5:02












    • While there is no prohibition, I consider it more elegant to have only one path to a resource - keeps all mental models simpler. I also prefer that URIs don't change their resource type if there is any nesting. for example /company/* should only return the company resource and not change resource type at all. None of this is specified by REST - its generally a poorly specified - just personal preference.
      – kashif
      Oct 2 '17 at 3:57










    9




    9




    This is pointing out the spirit of RESTful, there are no rules that say you should or should not do if only you consider a meaningful resource first. But further, I wonder what's the best practice for not duplicating code in such scenarios.
    – abookyun
    May 13 '15 at 3:18






    This is pointing out the spirit of RESTful, there are no rules that say you should or should not do if only you consider a meaningful resource first. But further, I wonder what's the best practice for not duplicating code in such scenarios.
    – abookyun
    May 13 '15 at 3:18






    9




    9




    @abookyun if you need both routes, then repeated controller code between them can be abstracted to service objects.
    – bgcode
    Dec 3 '15 at 20:37




    @abookyun if you need both routes, then repeated controller code between them can be abstracted to service objects.
    – bgcode
    Dec 3 '15 at 20:37












    This has nothing to do with REST. REST does not care about how you structure the path part of your URLs... all it cares about is valid, hopefully durable URIs...
    – redben
    Apr 5 '16 at 14:51




    This has nothing to do with REST. REST does not care about how you structure the path part of your URLs... all it cares about is valid, hopefully durable URIs...
    – redben
    Apr 5 '16 at 14:51












    Driving at this answer, I think any api where the dynamic segments are all unique identifiers shouldn't need to handle multiple dynamic segments (/company/3/department/2/employees/1). If the api provides ways to get each resource, then making each of those requests could be done in either a client side library or as a one-off endpoint that reuses code.
    – max
    Jul 3 '16 at 5:02






    Driving at this answer, I think any api where the dynamic segments are all unique identifiers shouldn't need to handle multiple dynamic segments (/company/3/department/2/employees/1). If the api provides ways to get each resource, then making each of those requests could be done in either a client side library or as a one-off endpoint that reuses code.
    – max
    Jul 3 '16 at 5:02














    While there is no prohibition, I consider it more elegant to have only one path to a resource - keeps all mental models simpler. I also prefer that URIs don't change their resource type if there is any nesting. for example /company/* should only return the company resource and not change resource type at all. None of this is specified by REST - its generally a poorly specified - just personal preference.
    – kashif
    Oct 2 '17 at 3:57






    While there is no prohibition, I consider it more elegant to have only one path to a resource - keeps all mental models simpler. I also prefer that URIs don't change their resource type if there is any nesting. for example /company/* should only return the company resource and not change resource type at all. None of this is specified by REST - its generally a poorly specified - just personal preference.
    – kashif
    Oct 2 '17 at 3:57














    up vote
    103
    down vote













    I've tried both design strategies - nested and non-nested endpoints. I've found that:




    1. if the nested resource has a primary key and you don't have its parent primary key, the nested structure requires you to get it, even though the system doesn't actually require it.


    2. nested endpoints typically require redundant endpoints. In other words, you will more often than not, need the additional /employees endpoint so you can get a list of employees across departments. If you have /employees, what exactly does /companies/departments/employees buy you?


    3. nesting endpoints don't evolve as nicely. E.g. you might not need to search for employees now but you might later and if you have a nested structure, you have no choice but to add another endpoint. With a non-nested design, you just add more parameters, which is simpler.


    4. sometimes a resource could have multiple types of parents. Resulting in multiple endpoints all returning the same resource.


    5. redundant endpoints makes the docs harder to write and also makes the api harder to learn.



    In short, the non-nested design seems to allow a more flexible and simpler endpoint schema.






    share|improve this answer

















    • 11




      Was very refreshing to come across this answer. I have been using nested endpoints for several months now after being taught that was the "right way". I came to all of the same conclusions you listed above. So much easier with a non-nested design.
      – user3344977
      Apr 20 '17 at 16:16












    • Would it also mean that primary key should be delivered a parameter of a query string instead of being delivered as a part of main url. /Employees?id=500, instead of /Employees/500. Wouldn't that also scale better in case you also require a primary key from a parent resource?
      – mko
      Nov 6 '17 at 12:32






    • 3




      You seem to list some of the downsides as upsides. "Just cram more parameters into a single end-point" makes the API harder to document and learn, not the other way around. ;-)
      – Drenmi
      Nov 21 '17 at 17:21






    • 3




      Not a fan of this answer. There's no need to introduce redundant endpoints just because you've added a nested resource. It's also not a problem to have the same resource returned by multiple parents, provided those parents genuinely own the nested resource. It's not a problem to get a parent resource to learn how to interact with the nested resources. A good discoverable REST API should do this.
      – Scottm
      Dec 11 '17 at 9:27






    • 1




      @Scottm - One drawback of nested resources that I came across is that it could lead to returning incorrect data if the parent resource ids are incorrect/mismatch. Assuming there are no authorization issues, it is left upto the api implementation to verify that the nested resource is indeed a child of the parent resource that is passed. If this check is not coded for, the api response could be incorrect leading to corruption. What are your thoughts?
      – Andy Dufresne
      Jul 12 at 14:40















    up vote
    103
    down vote













    I've tried both design strategies - nested and non-nested endpoints. I've found that:




    1. if the nested resource has a primary key and you don't have its parent primary key, the nested structure requires you to get it, even though the system doesn't actually require it.


    2. nested endpoints typically require redundant endpoints. In other words, you will more often than not, need the additional /employees endpoint so you can get a list of employees across departments. If you have /employees, what exactly does /companies/departments/employees buy you?


    3. nesting endpoints don't evolve as nicely. E.g. you might not need to search for employees now but you might later and if you have a nested structure, you have no choice but to add another endpoint. With a non-nested design, you just add more parameters, which is simpler.


    4. sometimes a resource could have multiple types of parents. Resulting in multiple endpoints all returning the same resource.


    5. redundant endpoints makes the docs harder to write and also makes the api harder to learn.



    In short, the non-nested design seems to allow a more flexible and simpler endpoint schema.






    share|improve this answer

















    • 11




      Was very refreshing to come across this answer. I have been using nested endpoints for several months now after being taught that was the "right way". I came to all of the same conclusions you listed above. So much easier with a non-nested design.
      – user3344977
      Apr 20 '17 at 16:16












    • Would it also mean that primary key should be delivered a parameter of a query string instead of being delivered as a part of main url. /Employees?id=500, instead of /Employees/500. Wouldn't that also scale better in case you also require a primary key from a parent resource?
      – mko
      Nov 6 '17 at 12:32






    • 3




      You seem to list some of the downsides as upsides. "Just cram more parameters into a single end-point" makes the API harder to document and learn, not the other way around. ;-)
      – Drenmi
      Nov 21 '17 at 17:21






    • 3




      Not a fan of this answer. There's no need to introduce redundant endpoints just because you've added a nested resource. It's also not a problem to have the same resource returned by multiple parents, provided those parents genuinely own the nested resource. It's not a problem to get a parent resource to learn how to interact with the nested resources. A good discoverable REST API should do this.
      – Scottm
      Dec 11 '17 at 9:27






    • 1




      @Scottm - One drawback of nested resources that I came across is that it could lead to returning incorrect data if the parent resource ids are incorrect/mismatch. Assuming there are no authorization issues, it is left upto the api implementation to verify that the nested resource is indeed a child of the parent resource that is passed. If this check is not coded for, the api response could be incorrect leading to corruption. What are your thoughts?
      – Andy Dufresne
      Jul 12 at 14:40













    up vote
    103
    down vote










    up vote
    103
    down vote









    I've tried both design strategies - nested and non-nested endpoints. I've found that:




    1. if the nested resource has a primary key and you don't have its parent primary key, the nested structure requires you to get it, even though the system doesn't actually require it.


    2. nested endpoints typically require redundant endpoints. In other words, you will more often than not, need the additional /employees endpoint so you can get a list of employees across departments. If you have /employees, what exactly does /companies/departments/employees buy you?


    3. nesting endpoints don't evolve as nicely. E.g. you might not need to search for employees now but you might later and if you have a nested structure, you have no choice but to add another endpoint. With a non-nested design, you just add more parameters, which is simpler.


    4. sometimes a resource could have multiple types of parents. Resulting in multiple endpoints all returning the same resource.


    5. redundant endpoints makes the docs harder to write and also makes the api harder to learn.



    In short, the non-nested design seems to allow a more flexible and simpler endpoint schema.






    share|improve this answer












    I've tried both design strategies - nested and non-nested endpoints. I've found that:




    1. if the nested resource has a primary key and you don't have its parent primary key, the nested structure requires you to get it, even though the system doesn't actually require it.


    2. nested endpoints typically require redundant endpoints. In other words, you will more often than not, need the additional /employees endpoint so you can get a list of employees across departments. If you have /employees, what exactly does /companies/departments/employees buy you?


    3. nesting endpoints don't evolve as nicely. E.g. you might not need to search for employees now but you might later and if you have a nested structure, you have no choice but to add another endpoint. With a non-nested design, you just add more parameters, which is simpler.


    4. sometimes a resource could have multiple types of parents. Resulting in multiple endpoints all returning the same resource.


    5. redundant endpoints makes the docs harder to write and also makes the api harder to learn.



    In short, the non-nested design seems to allow a more flexible and simpler endpoint schema.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Apr 4 '16 at 19:01









    Patc

    1,047142




    1,047142








    • 11




      Was very refreshing to come across this answer. I have been using nested endpoints for several months now after being taught that was the "right way". I came to all of the same conclusions you listed above. So much easier with a non-nested design.
      – user3344977
      Apr 20 '17 at 16:16












    • Would it also mean that primary key should be delivered a parameter of a query string instead of being delivered as a part of main url. /Employees?id=500, instead of /Employees/500. Wouldn't that also scale better in case you also require a primary key from a parent resource?
      – mko
      Nov 6 '17 at 12:32






    • 3




      You seem to list some of the downsides as upsides. "Just cram more parameters into a single end-point" makes the API harder to document and learn, not the other way around. ;-)
      – Drenmi
      Nov 21 '17 at 17:21






    • 3




      Not a fan of this answer. There's no need to introduce redundant endpoints just because you've added a nested resource. It's also not a problem to have the same resource returned by multiple parents, provided those parents genuinely own the nested resource. It's not a problem to get a parent resource to learn how to interact with the nested resources. A good discoverable REST API should do this.
      – Scottm
      Dec 11 '17 at 9:27






    • 1




      @Scottm - One drawback of nested resources that I came across is that it could lead to returning incorrect data if the parent resource ids are incorrect/mismatch. Assuming there are no authorization issues, it is left upto the api implementation to verify that the nested resource is indeed a child of the parent resource that is passed. If this check is not coded for, the api response could be incorrect leading to corruption. What are your thoughts?
      – Andy Dufresne
      Jul 12 at 14:40














    • 11




      Was very refreshing to come across this answer. I have been using nested endpoints for several months now after being taught that was the "right way". I came to all of the same conclusions you listed above. So much easier with a non-nested design.
      – user3344977
      Apr 20 '17 at 16:16












    • Would it also mean that primary key should be delivered a parameter of a query string instead of being delivered as a part of main url. /Employees?id=500, instead of /Employees/500. Wouldn't that also scale better in case you also require a primary key from a parent resource?
      – mko
      Nov 6 '17 at 12:32






    • 3




      You seem to list some of the downsides as upsides. "Just cram more parameters into a single end-point" makes the API harder to document and learn, not the other way around. ;-)
      – Drenmi
      Nov 21 '17 at 17:21






    • 3




      Not a fan of this answer. There's no need to introduce redundant endpoints just because you've added a nested resource. It's also not a problem to have the same resource returned by multiple parents, provided those parents genuinely own the nested resource. It's not a problem to get a parent resource to learn how to interact with the nested resources. A good discoverable REST API should do this.
      – Scottm
      Dec 11 '17 at 9:27






    • 1




      @Scottm - One drawback of nested resources that I came across is that it could lead to returning incorrect data if the parent resource ids are incorrect/mismatch. Assuming there are no authorization issues, it is left upto the api implementation to verify that the nested resource is indeed a child of the parent resource that is passed. If this check is not coded for, the api response could be incorrect leading to corruption. What are your thoughts?
      – Andy Dufresne
      Jul 12 at 14:40








    11




    11




    Was very refreshing to come across this answer. I have been using nested endpoints for several months now after being taught that was the "right way". I came to all of the same conclusions you listed above. So much easier with a non-nested design.
    – user3344977
    Apr 20 '17 at 16:16






    Was very refreshing to come across this answer. I have been using nested endpoints for several months now after being taught that was the "right way". I came to all of the same conclusions you listed above. So much easier with a non-nested design.
    – user3344977
    Apr 20 '17 at 16:16














    Would it also mean that primary key should be delivered a parameter of a query string instead of being delivered as a part of main url. /Employees?id=500, instead of /Employees/500. Wouldn't that also scale better in case you also require a primary key from a parent resource?
    – mko
    Nov 6 '17 at 12:32




    Would it also mean that primary key should be delivered a parameter of a query string instead of being delivered as a part of main url. /Employees?id=500, instead of /Employees/500. Wouldn't that also scale better in case you also require a primary key from a parent resource?
    – mko
    Nov 6 '17 at 12:32




    3




    3




    You seem to list some of the downsides as upsides. "Just cram more parameters into a single end-point" makes the API harder to document and learn, not the other way around. ;-)
    – Drenmi
    Nov 21 '17 at 17:21




    You seem to list some of the downsides as upsides. "Just cram more parameters into a single end-point" makes the API harder to document and learn, not the other way around. ;-)
    – Drenmi
    Nov 21 '17 at 17:21




    3




    3




    Not a fan of this answer. There's no need to introduce redundant endpoints just because you've added a nested resource. It's also not a problem to have the same resource returned by multiple parents, provided those parents genuinely own the nested resource. It's not a problem to get a parent resource to learn how to interact with the nested resources. A good discoverable REST API should do this.
    – Scottm
    Dec 11 '17 at 9:27




    Not a fan of this answer. There's no need to introduce redundant endpoints just because you've added a nested resource. It's also not a problem to have the same resource returned by multiple parents, provided those parents genuinely own the nested resource. It's not a problem to get a parent resource to learn how to interact with the nested resources. A good discoverable REST API should do this.
    – Scottm
    Dec 11 '17 at 9:27




    1




    1




    @Scottm - One drawback of nested resources that I came across is that it could lead to returning incorrect data if the parent resource ids are incorrect/mismatch. Assuming there are no authorization issues, it is left upto the api implementation to verify that the nested resource is indeed a child of the parent resource that is passed. If this check is not coded for, the api response could be incorrect leading to corruption. What are your thoughts?
    – Andy Dufresne
    Jul 12 at 14:40




    @Scottm - One drawback of nested resources that I came across is that it could lead to returning incorrect data if the parent resource ids are incorrect/mismatch. Assuming there are no authorization issues, it is left upto the api implementation to verify that the nested resource is indeed a child of the parent resource that is passed. If this check is not coded for, the api response could be incorrect leading to corruption. What are your thoughts?
    – Andy Dufresne
    Jul 12 at 14:40










    up vote
    53
    down vote













    I've moved what I've done from the question to an answer where more people are likely to see it.



    What I've done is to have the creation endpoints at the nested endpoint, The canonical endpoint for modifying or querying an item is not at the nested resource.



    So in this example (just listing the endpoints that change a resource)





    • POST /companies/ creates a new company returns a link to the created company.


    • POST /companies/{companyId}/departments when a department is put creates the new department returns a link to /departments/{departmentId}


    • PUT /departments/{departmentId} modifies a department


    • POST /departments/{deparmentId}/employees creates a new employee returns a link to /employees/{employeeId}


    So there are root level resources for each of the collections. However the create is in the owning object.






    share|improve this answer



















    • 2




      I have come up with the same type of design as well. I think it's intuitive to create things like this "where they belong", but then still be able to list them globally. Even more so when there's a relationship where a resource MUST have a parent. Then creating that resource globally does not make that obvious, but doing it in a sub-resource like this makes perfect sense.
      – Joakim
      Sep 11 '16 at 20:27










    • I guess you used POST meaning PUT, and otherwise.
      – Gerardo Lima
      Jan 18 at 15:43










    • Actually no Note that I'm not using pre assigned Ids for creation as the server in this case is responsible for returning the id (in the link). Therefore writing POST is correct (can't do a get on the same implementation). The put however changes the entire resource but its still available at the same location so I PUT it. PUT vs POST is a different matter and is controversial too. For example stackoverflow.com/questions/630453/put-vs-post-in-rest
      – Wes
      Jan 18 at 16:57












    • @Wes Even I prefer modifying verb methods to be under the parent. But, do you see passing query parameter for global resource is accepted well? Ex : POST /departments with query parameter company=company-id
      – Ayyappa
      Apr 9 at 12:48












    • @Ayyappa Its not something I would personally do, but I woudn't be too shocked if it did happen. Normally I don't like mixing query strings with posted bodies. But I have done it in the past many years ago.
      – Wes
      Apr 11 at 8:03















    up vote
    53
    down vote













    I've moved what I've done from the question to an answer where more people are likely to see it.



    What I've done is to have the creation endpoints at the nested endpoint, The canonical endpoint for modifying or querying an item is not at the nested resource.



    So in this example (just listing the endpoints that change a resource)





    • POST /companies/ creates a new company returns a link to the created company.


    • POST /companies/{companyId}/departments when a department is put creates the new department returns a link to /departments/{departmentId}


    • PUT /departments/{departmentId} modifies a department


    • POST /departments/{deparmentId}/employees creates a new employee returns a link to /employees/{employeeId}


    So there are root level resources for each of the collections. However the create is in the owning object.






    share|improve this answer



















    • 2




      I have come up with the same type of design as well. I think it's intuitive to create things like this "where they belong", but then still be able to list them globally. Even more so when there's a relationship where a resource MUST have a parent. Then creating that resource globally does not make that obvious, but doing it in a sub-resource like this makes perfect sense.
      – Joakim
      Sep 11 '16 at 20:27










    • I guess you used POST meaning PUT, and otherwise.
      – Gerardo Lima
      Jan 18 at 15:43










    • Actually no Note that I'm not using pre assigned Ids for creation as the server in this case is responsible for returning the id (in the link). Therefore writing POST is correct (can't do a get on the same implementation). The put however changes the entire resource but its still available at the same location so I PUT it. PUT vs POST is a different matter and is controversial too. For example stackoverflow.com/questions/630453/put-vs-post-in-rest
      – Wes
      Jan 18 at 16:57












    • @Wes Even I prefer modifying verb methods to be under the parent. But, do you see passing query parameter for global resource is accepted well? Ex : POST /departments with query parameter company=company-id
      – Ayyappa
      Apr 9 at 12:48












    • @Ayyappa Its not something I would personally do, but I woudn't be too shocked if it did happen. Normally I don't like mixing query strings with posted bodies. But I have done it in the past many years ago.
      – Wes
      Apr 11 at 8:03













    up vote
    53
    down vote










    up vote
    53
    down vote









    I've moved what I've done from the question to an answer where more people are likely to see it.



    What I've done is to have the creation endpoints at the nested endpoint, The canonical endpoint for modifying or querying an item is not at the nested resource.



    So in this example (just listing the endpoints that change a resource)





    • POST /companies/ creates a new company returns a link to the created company.


    • POST /companies/{companyId}/departments when a department is put creates the new department returns a link to /departments/{departmentId}


    • PUT /departments/{departmentId} modifies a department


    • POST /departments/{deparmentId}/employees creates a new employee returns a link to /employees/{employeeId}


    So there are root level resources for each of the collections. However the create is in the owning object.






    share|improve this answer














    I've moved what I've done from the question to an answer where more people are likely to see it.



    What I've done is to have the creation endpoints at the nested endpoint, The canonical endpoint for modifying or querying an item is not at the nested resource.



    So in this example (just listing the endpoints that change a resource)





    • POST /companies/ creates a new company returns a link to the created company.


    • POST /companies/{companyId}/departments when a department is put creates the new department returns a link to /departments/{departmentId}


    • PUT /departments/{departmentId} modifies a department


    • POST /departments/{deparmentId}/employees creates a new employee returns a link to /employees/{employeeId}


    So there are root level resources for each of the collections. However the create is in the owning object.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Aug 29 at 12:11

























    answered Sep 28 '15 at 10:27









    Wes

    2,48422350




    2,48422350








    • 2




      I have come up with the same type of design as well. I think it's intuitive to create things like this "where they belong", but then still be able to list them globally. Even more so when there's a relationship where a resource MUST have a parent. Then creating that resource globally does not make that obvious, but doing it in a sub-resource like this makes perfect sense.
      – Joakim
      Sep 11 '16 at 20:27










    • I guess you used POST meaning PUT, and otherwise.
      – Gerardo Lima
      Jan 18 at 15:43










    • Actually no Note that I'm not using pre assigned Ids for creation as the server in this case is responsible for returning the id (in the link). Therefore writing POST is correct (can't do a get on the same implementation). The put however changes the entire resource but its still available at the same location so I PUT it. PUT vs POST is a different matter and is controversial too. For example stackoverflow.com/questions/630453/put-vs-post-in-rest
      – Wes
      Jan 18 at 16:57












    • @Wes Even I prefer modifying verb methods to be under the parent. But, do you see passing query parameter for global resource is accepted well? Ex : POST /departments with query parameter company=company-id
      – Ayyappa
      Apr 9 at 12:48












    • @Ayyappa Its not something I would personally do, but I woudn't be too shocked if it did happen. Normally I don't like mixing query strings with posted bodies. But I have done it in the past many years ago.
      – Wes
      Apr 11 at 8:03














    • 2




      I have come up with the same type of design as well. I think it's intuitive to create things like this "where they belong", but then still be able to list them globally. Even more so when there's a relationship where a resource MUST have a parent. Then creating that resource globally does not make that obvious, but doing it in a sub-resource like this makes perfect sense.
      – Joakim
      Sep 11 '16 at 20:27










    • I guess you used POST meaning PUT, and otherwise.
      – Gerardo Lima
      Jan 18 at 15:43










    • Actually no Note that I'm not using pre assigned Ids for creation as the server in this case is responsible for returning the id (in the link). Therefore writing POST is correct (can't do a get on the same implementation). The put however changes the entire resource but its still available at the same location so I PUT it. PUT vs POST is a different matter and is controversial too. For example stackoverflow.com/questions/630453/put-vs-post-in-rest
      – Wes
      Jan 18 at 16:57












    • @Wes Even I prefer modifying verb methods to be under the parent. But, do you see passing query parameter for global resource is accepted well? Ex : POST /departments with query parameter company=company-id
      – Ayyappa
      Apr 9 at 12:48












    • @Ayyappa Its not something I would personally do, but I woudn't be too shocked if it did happen. Normally I don't like mixing query strings with posted bodies. But I have done it in the past many years ago.
      – Wes
      Apr 11 at 8:03








    2




    2




    I have come up with the same type of design as well. I think it's intuitive to create things like this "where they belong", but then still be able to list them globally. Even more so when there's a relationship where a resource MUST have a parent. Then creating that resource globally does not make that obvious, but doing it in a sub-resource like this makes perfect sense.
    – Joakim
    Sep 11 '16 at 20:27




    I have come up with the same type of design as well. I think it's intuitive to create things like this "where they belong", but then still be able to list them globally. Even more so when there's a relationship where a resource MUST have a parent. Then creating that resource globally does not make that obvious, but doing it in a sub-resource like this makes perfect sense.
    – Joakim
    Sep 11 '16 at 20:27












    I guess you used POST meaning PUT, and otherwise.
    – Gerardo Lima
    Jan 18 at 15:43




    I guess you used POST meaning PUT, and otherwise.
    – Gerardo Lima
    Jan 18 at 15:43












    Actually no Note that I'm not using pre assigned Ids for creation as the server in this case is responsible for returning the id (in the link). Therefore writing POST is correct (can't do a get on the same implementation). The put however changes the entire resource but its still available at the same location so I PUT it. PUT vs POST is a different matter and is controversial too. For example stackoverflow.com/questions/630453/put-vs-post-in-rest
    – Wes
    Jan 18 at 16:57






    Actually no Note that I'm not using pre assigned Ids for creation as the server in this case is responsible for returning the id (in the link). Therefore writing POST is correct (can't do a get on the same implementation). The put however changes the entire resource but its still available at the same location so I PUT it. PUT vs POST is a different matter and is controversial too. For example stackoverflow.com/questions/630453/put-vs-post-in-rest
    – Wes
    Jan 18 at 16:57














    @Wes Even I prefer modifying verb methods to be under the parent. But, do you see passing query parameter for global resource is accepted well? Ex : POST /departments with query parameter company=company-id
    – Ayyappa
    Apr 9 at 12:48






    @Wes Even I prefer modifying verb methods to be under the parent. But, do you see passing query parameter for global resource is accepted well? Ex : POST /departments with query parameter company=company-id
    – Ayyappa
    Apr 9 at 12:48














    @Ayyappa Its not something I would personally do, but I woudn't be too shocked if it did happen. Normally I don't like mixing query strings with posted bodies. But I have done it in the past many years ago.
    – Wes
    Apr 11 at 8:03




    @Ayyappa Its not something I would personally do, but I woudn't be too shocked if it did happen. Normally I don't like mixing query strings with posted bodies. But I have done it in the past many years ago.
    – Wes
    Apr 11 at 8:03










    up vote
    6
    down vote













    I disagree with this kind of path



    GET /companies/{companyId}/departments


    If you want to get departments, I think it's better to use a /departments resource



    GET /departments?companyId=123


    I suppose you have a companies table and a departments table then classes to map them in the programming language you use. I also assume that departments could be attached to other entities than companies, so a /departments resource is straightforward, it's convenient to have resources mapped to tables and also you don't need as many endpoints since you can reuse



    GET /departments?companyId=123


    for any kind of search, for instance



    GET /departments?name=xxx
    GET /departments?companyId=123&name=xxx
    etc.


    If you want to create a department, the



    POST /departments


    resource should be used and the request body should contain the company ID (if the department can be linked to only one company).






    share|improve this answer























    • To me, this is an acceptable approach only if the nested object makes sense as an atomic object. If they are not, It wouldnt really make sense to break them apart.
      – Simon Aronsson
      Sep 26 '16 at 10:26










    • This is what I said, if you also want to be able to retrieve departments, meaning if you'll use a /departments endpoint.
      – Maxime Laval
      Sep 26 '16 at 17:21






    • 2




      It may also make sense to allow departments to be included via lazy loading when fetching a company, eg GET /companies/{companyId}?include=departments, since this allows both the company and its departments to be fetched in a single HTTP request. Fractal does this really well.
      – Matthew Daly
      Jul 27 '17 at 11:31










    • When you're setting up acls you probably want to restrict the /departments endpoint to only be accessible by an admin, and have each company access their own departments only through ` /companies/{companyId}/departments`
      – Cuzox
      Dec 26 '17 at 13:34










    • @MatthewDaly OData also does that nicely with $expand
      – Robert Grant
      Jan 2 at 10:37















    up vote
    6
    down vote













    I disagree with this kind of path



    GET /companies/{companyId}/departments


    If you want to get departments, I think it's better to use a /departments resource



    GET /departments?companyId=123


    I suppose you have a companies table and a departments table then classes to map them in the programming language you use. I also assume that departments could be attached to other entities than companies, so a /departments resource is straightforward, it's convenient to have resources mapped to tables and also you don't need as many endpoints since you can reuse



    GET /departments?companyId=123


    for any kind of search, for instance



    GET /departments?name=xxx
    GET /departments?companyId=123&name=xxx
    etc.


    If you want to create a department, the



    POST /departments


    resource should be used and the request body should contain the company ID (if the department can be linked to only one company).






    share|improve this answer























    • To me, this is an acceptable approach only if the nested object makes sense as an atomic object. If they are not, It wouldnt really make sense to break them apart.
      – Simon Aronsson
      Sep 26 '16 at 10:26










    • This is what I said, if you also want to be able to retrieve departments, meaning if you'll use a /departments endpoint.
      – Maxime Laval
      Sep 26 '16 at 17:21






    • 2




      It may also make sense to allow departments to be included via lazy loading when fetching a company, eg GET /companies/{companyId}?include=departments, since this allows both the company and its departments to be fetched in a single HTTP request. Fractal does this really well.
      – Matthew Daly
      Jul 27 '17 at 11:31










    • When you're setting up acls you probably want to restrict the /departments endpoint to only be accessible by an admin, and have each company access their own departments only through ` /companies/{companyId}/departments`
      – Cuzox
      Dec 26 '17 at 13:34










    • @MatthewDaly OData also does that nicely with $expand
      – Robert Grant
      Jan 2 at 10:37













    up vote
    6
    down vote










    up vote
    6
    down vote









    I disagree with this kind of path



    GET /companies/{companyId}/departments


    If you want to get departments, I think it's better to use a /departments resource



    GET /departments?companyId=123


    I suppose you have a companies table and a departments table then classes to map them in the programming language you use. I also assume that departments could be attached to other entities than companies, so a /departments resource is straightforward, it's convenient to have resources mapped to tables and also you don't need as many endpoints since you can reuse



    GET /departments?companyId=123


    for any kind of search, for instance



    GET /departments?name=xxx
    GET /departments?companyId=123&name=xxx
    etc.


    If you want to create a department, the



    POST /departments


    resource should be used and the request body should contain the company ID (if the department can be linked to only one company).






    share|improve this answer














    I disagree with this kind of path



    GET /companies/{companyId}/departments


    If you want to get departments, I think it's better to use a /departments resource



    GET /departments?companyId=123


    I suppose you have a companies table and a departments table then classes to map them in the programming language you use. I also assume that departments could be attached to other entities than companies, so a /departments resource is straightforward, it's convenient to have resources mapped to tables and also you don't need as many endpoints since you can reuse



    GET /departments?companyId=123


    for any kind of search, for instance



    GET /departments?name=xxx
    GET /departments?companyId=123&name=xxx
    etc.


    If you want to create a department, the



    POST /departments


    resource should be used and the request body should contain the company ID (if the department can be linked to only one company).







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Feb 13 '16 at 18:54

























    answered Feb 13 '16 at 18:33









    Maxime Laval

    1,30532147




    1,30532147












    • To me, this is an acceptable approach only if the nested object makes sense as an atomic object. If they are not, It wouldnt really make sense to break them apart.
      – Simon Aronsson
      Sep 26 '16 at 10:26










    • This is what I said, if you also want to be able to retrieve departments, meaning if you'll use a /departments endpoint.
      – Maxime Laval
      Sep 26 '16 at 17:21






    • 2




      It may also make sense to allow departments to be included via lazy loading when fetching a company, eg GET /companies/{companyId}?include=departments, since this allows both the company and its departments to be fetched in a single HTTP request. Fractal does this really well.
      – Matthew Daly
      Jul 27 '17 at 11:31










    • When you're setting up acls you probably want to restrict the /departments endpoint to only be accessible by an admin, and have each company access their own departments only through ` /companies/{companyId}/departments`
      – Cuzox
      Dec 26 '17 at 13:34










    • @MatthewDaly OData also does that nicely with $expand
      – Robert Grant
      Jan 2 at 10:37


















    • To me, this is an acceptable approach only if the nested object makes sense as an atomic object. If they are not, It wouldnt really make sense to break them apart.
      – Simon Aronsson
      Sep 26 '16 at 10:26










    • This is what I said, if you also want to be able to retrieve departments, meaning if you'll use a /departments endpoint.
      – Maxime Laval
      Sep 26 '16 at 17:21






    • 2




      It may also make sense to allow departments to be included via lazy loading when fetching a company, eg GET /companies/{companyId}?include=departments, since this allows both the company and its departments to be fetched in a single HTTP request. Fractal does this really well.
      – Matthew Daly
      Jul 27 '17 at 11:31










    • When you're setting up acls you probably want to restrict the /departments endpoint to only be accessible by an admin, and have each company access their own departments only through ` /companies/{companyId}/departments`
      – Cuzox
      Dec 26 '17 at 13:34










    • @MatthewDaly OData also does that nicely with $expand
      – Robert Grant
      Jan 2 at 10:37
















    To me, this is an acceptable approach only if the nested object makes sense as an atomic object. If they are not, It wouldnt really make sense to break them apart.
    – Simon Aronsson
    Sep 26 '16 at 10:26




    To me, this is an acceptable approach only if the nested object makes sense as an atomic object. If they are not, It wouldnt really make sense to break them apart.
    – Simon Aronsson
    Sep 26 '16 at 10:26












    This is what I said, if you also want to be able to retrieve departments, meaning if you'll use a /departments endpoint.
    – Maxime Laval
    Sep 26 '16 at 17:21




    This is what I said, if you also want to be able to retrieve departments, meaning if you'll use a /departments endpoint.
    – Maxime Laval
    Sep 26 '16 at 17:21




    2




    2




    It may also make sense to allow departments to be included via lazy loading when fetching a company, eg GET /companies/{companyId}?include=departments, since this allows both the company and its departments to be fetched in a single HTTP request. Fractal does this really well.
    – Matthew Daly
    Jul 27 '17 at 11:31




    It may also make sense to allow departments to be included via lazy loading when fetching a company, eg GET /companies/{companyId}?include=departments, since this allows both the company and its departments to be fetched in a single HTTP request. Fractal does this really well.
    – Matthew Daly
    Jul 27 '17 at 11:31












    When you're setting up acls you probably want to restrict the /departments endpoint to only be accessible by an admin, and have each company access their own departments only through ` /companies/{companyId}/departments`
    – Cuzox
    Dec 26 '17 at 13:34




    When you're setting up acls you probably want to restrict the /departments endpoint to only be accessible by an admin, and have each company access their own departments only through ` /companies/{companyId}/departments`
    – Cuzox
    Dec 26 '17 at 13:34












    @MatthewDaly OData also does that nicely with $expand
    – Robert Grant
    Jan 2 at 10:37




    @MatthewDaly OData also does that nicely with $expand
    – Robert Grant
    Jan 2 at 10:37










    up vote
    6
    down vote













    How your URLs look have nothing to do with REST. Anything goes. It actually is an "implementation detail". So just like how you name your variables. All they have to be is unique and durable.



    Don't waste too much time on this, just make a choice and stick to it/be consistent. For example if you go with hierarchies then you do it for all your resources. If you go with query parameters...etc just like naming conventions in your code.



    Why so ? As far as I know a "RESTful" API is to be browsable (you know..."Hypermedia as the Engine of Application State"), therefore an API client does not care about what your URLs are like as long as they're valid (there's no SEO, no human that needs to read those "friendly urls", except may be for debugging...)



    How nice/understandable a URL is in a REST API is only interesting to you as the API developer, not the API client, as would the name of a variable in your code be.



    The most important thing is that your API client know how to interpret your media type.
    For example it knows that :




    • your media type has a links property that lists available/related links.

    • Each link is identified by a relationship (just like browsers know that link[rel="stylesheet"] means its a style sheet or rel=favico is a link to a favicon...)

    • and it knowns what those relationships mean ("companies" mean a list of companies,"search" means a templated url for doing a search on a list of resource, "departments" means departments of the current resource )


    Below is an example HTTP exchange (bodies are in yaml since it's easier to write):



    Request



    GET / HTTP/1.1
    Host: api.acme.io
    Accept: text/yaml, text/acme-mediatype+yaml


    Response: a list of links to main resource (companies, people, whatever...)



    HTTP/1.1 200 OK
    Date: Tue, 05 Apr 2016 15:04:00 GMT
    Last-Modified: Tue, 05 Apr 2016 00:00:00 GMT
    Content-Type: text/acme-mediatype+yaml

    # body: this is your API's entrypoint (like a homepage)
    links:
    # could be some random path https://api.acme.local/modskmklmkdsml
    # the only thing the API client cares about is the key (or rel) "companies"
    companies: https://api.acme.local/companies
    people: https://api.acme.local/people


    Request: link to companies (using previous response's body.links.companies)



    GET /companies HTTP/1.1
    Host: api.acme.local
    Accept: text/yaml, text/acme-mediatype+yaml


    Response: a partial list of companies (under items), the resource contains related links, like link to get the next couple of companies (body.links.next) an other (templated) link to search (body.links.search)



    HTTP/1.1 200 OK
    Date: Tue, 05 Apr 2016 15:06:00 GMT
    Last-Modified: Tue, 05 Apr 2016 00:00:00 GMT
    Content-Type: text/acme-mediatype+yaml

    # body: representation of a list of companies
    links:
    # link to the next page
    next: https://api.acme.local/companies?page=2
    # templated link for search
    search: https://api.acme.local/companies?query={query}
    # you could provide available actions related to this resource
    actions:
    add:
    href: https://api.acme.local/companies
    method: POST
    items:
    - name: company1
    links:
    self: https://api.acme.local/companies/8er13eo
    # and here is the link to departments
    # again the client only cares about the key department
    department: https://api.acme.local/companies/8er13eo/departments
    - name: company2
    links:
    self: https://api.acme.local/companies/9r13d4l
    # or could be in some other location !
    department: https://api2.acme.local/departments?company=8er13eo


    So as you see if you go the links/relations way how you structure the path part of your URLs does't have any value to your API client. And if your are communicating the structure of your URLs to your client as documentation, then your are not doing REST (or at least not Level 3 as per "Richardson's maturity model")






    share|improve this answer



















    • 6




      "How nice/understandable a URL is in a REST API is only interesting to you as the API developer, not the API client, as would the name of a variable in your code be." Why would this NOT be interesting? This is very important, if anyone but yourself is also using the API. This is part of the user experience, so I would say it is very important that this is easy to understand for the API client developers. Making things even more easy to understand by linking resources clearly is of course a bonus (level 3 in the url you provide). Everything should be intuitive and logical with clear relations.
      – Joakim
      Sep 11 '16 at 20:33






    • 1




      @Joakim If you are making a level 3 rest API (Hypertext As The Engine Of Application State), then the url's path structure is absolutely of no interest to the client (as long as it is valid). If you are not aiming for level 3, then yes, it is important and should be guessable. But real REST is level 3. A good article: martinfowler.com/articles/richardsonMaturityModel.html
      – redben
      Sep 11 '16 at 21:19






    • 3




      I object to ever creating an API or UI that is not user friendly for human beings. Level 3 or not, I agree linking resources is a great idea. But to suggest doing so "makes it possible to change URL scheme" is to be out of touch with reality, and how people use APIs. So it's a bad recommendation. But sure in the best of all worlds everyone would be at Level 3 REST. I incorporate hyperlinks AND use a humanly understandable URL scheme. Level 3 does not exclude the former, and one SHOULD care in my opinion. Good article though :)
      – Joakim
      Sep 11 '16 at 21:29










    • One should of course care for the sake of maintainability and other concerns, I think you miss the point of my answer : the way the url looks does not deserve a lot of thinking and you should "just make a choice and stick to it/be consistent" as I said in the answer. And in the case of a REST API, at least my opinion, user friendlyness is not in the url, it is mostly in (the media type) Anyway I hope you understand my point :)
      – redben
      Sep 11 '16 at 22:14

















    up vote
    6
    down vote













    How your URLs look have nothing to do with REST. Anything goes. It actually is an "implementation detail". So just like how you name your variables. All they have to be is unique and durable.



    Don't waste too much time on this, just make a choice and stick to it/be consistent. For example if you go with hierarchies then you do it for all your resources. If you go with query parameters...etc just like naming conventions in your code.



    Why so ? As far as I know a "RESTful" API is to be browsable (you know..."Hypermedia as the Engine of Application State"), therefore an API client does not care about what your URLs are like as long as they're valid (there's no SEO, no human that needs to read those "friendly urls", except may be for debugging...)



    How nice/understandable a URL is in a REST API is only interesting to you as the API developer, not the API client, as would the name of a variable in your code be.



    The most important thing is that your API client know how to interpret your media type.
    For example it knows that :




    • your media type has a links property that lists available/related links.

    • Each link is identified by a relationship (just like browsers know that link[rel="stylesheet"] means its a style sheet or rel=favico is a link to a favicon...)

    • and it knowns what those relationships mean ("companies" mean a list of companies,"search" means a templated url for doing a search on a list of resource, "departments" means departments of the current resource )


    Below is an example HTTP exchange (bodies are in yaml since it's easier to write):



    Request



    GET / HTTP/1.1
    Host: api.acme.io
    Accept: text/yaml, text/acme-mediatype+yaml


    Response: a list of links to main resource (companies, people, whatever...)



    HTTP/1.1 200 OK
    Date: Tue, 05 Apr 2016 15:04:00 GMT
    Last-Modified: Tue, 05 Apr 2016 00:00:00 GMT
    Content-Type: text/acme-mediatype+yaml

    # body: this is your API's entrypoint (like a homepage)
    links:
    # could be some random path https://api.acme.local/modskmklmkdsml
    # the only thing the API client cares about is the key (or rel) "companies"
    companies: https://api.acme.local/companies
    people: https://api.acme.local/people


    Request: link to companies (using previous response's body.links.companies)



    GET /companies HTTP/1.1
    Host: api.acme.local
    Accept: text/yaml, text/acme-mediatype+yaml


    Response: a partial list of companies (under items), the resource contains related links, like link to get the next couple of companies (body.links.next) an other (templated) link to search (body.links.search)



    HTTP/1.1 200 OK
    Date: Tue, 05 Apr 2016 15:06:00 GMT
    Last-Modified: Tue, 05 Apr 2016 00:00:00 GMT
    Content-Type: text/acme-mediatype+yaml

    # body: representation of a list of companies
    links:
    # link to the next page
    next: https://api.acme.local/companies?page=2
    # templated link for search
    search: https://api.acme.local/companies?query={query}
    # you could provide available actions related to this resource
    actions:
    add:
    href: https://api.acme.local/companies
    method: POST
    items:
    - name: company1
    links:
    self: https://api.acme.local/companies/8er13eo
    # and here is the link to departments
    # again the client only cares about the key department
    department: https://api.acme.local/companies/8er13eo/departments
    - name: company2
    links:
    self: https://api.acme.local/companies/9r13d4l
    # or could be in some other location !
    department: https://api2.acme.local/departments?company=8er13eo


    So as you see if you go the links/relations way how you structure the path part of your URLs does't have any value to your API client. And if your are communicating the structure of your URLs to your client as documentation, then your are not doing REST (or at least not Level 3 as per "Richardson's maturity model")






    share|improve this answer



















    • 6




      "How nice/understandable a URL is in a REST API is only interesting to you as the API developer, not the API client, as would the name of a variable in your code be." Why would this NOT be interesting? This is very important, if anyone but yourself is also using the API. This is part of the user experience, so I would say it is very important that this is easy to understand for the API client developers. Making things even more easy to understand by linking resources clearly is of course a bonus (level 3 in the url you provide). Everything should be intuitive and logical with clear relations.
      – Joakim
      Sep 11 '16 at 20:33






    • 1




      @Joakim If you are making a level 3 rest API (Hypertext As The Engine Of Application State), then the url's path structure is absolutely of no interest to the client (as long as it is valid). If you are not aiming for level 3, then yes, it is important and should be guessable. But real REST is level 3. A good article: martinfowler.com/articles/richardsonMaturityModel.html
      – redben
      Sep 11 '16 at 21:19






    • 3




      I object to ever creating an API or UI that is not user friendly for human beings. Level 3 or not, I agree linking resources is a great idea. But to suggest doing so "makes it possible to change URL scheme" is to be out of touch with reality, and how people use APIs. So it's a bad recommendation. But sure in the best of all worlds everyone would be at Level 3 REST. I incorporate hyperlinks AND use a humanly understandable URL scheme. Level 3 does not exclude the former, and one SHOULD care in my opinion. Good article though :)
      – Joakim
      Sep 11 '16 at 21:29










    • One should of course care for the sake of maintainability and other concerns, I think you miss the point of my answer : the way the url looks does not deserve a lot of thinking and you should "just make a choice and stick to it/be consistent" as I said in the answer. And in the case of a REST API, at least my opinion, user friendlyness is not in the url, it is mostly in (the media type) Anyway I hope you understand my point :)
      – redben
      Sep 11 '16 at 22:14















    up vote
    6
    down vote










    up vote
    6
    down vote









    How your URLs look have nothing to do with REST. Anything goes. It actually is an "implementation detail". So just like how you name your variables. All they have to be is unique and durable.



    Don't waste too much time on this, just make a choice and stick to it/be consistent. For example if you go with hierarchies then you do it for all your resources. If you go with query parameters...etc just like naming conventions in your code.



    Why so ? As far as I know a "RESTful" API is to be browsable (you know..."Hypermedia as the Engine of Application State"), therefore an API client does not care about what your URLs are like as long as they're valid (there's no SEO, no human that needs to read those "friendly urls", except may be for debugging...)



    How nice/understandable a URL is in a REST API is only interesting to you as the API developer, not the API client, as would the name of a variable in your code be.



    The most important thing is that your API client know how to interpret your media type.
    For example it knows that :




    • your media type has a links property that lists available/related links.

    • Each link is identified by a relationship (just like browsers know that link[rel="stylesheet"] means its a style sheet or rel=favico is a link to a favicon...)

    • and it knowns what those relationships mean ("companies" mean a list of companies,"search" means a templated url for doing a search on a list of resource, "departments" means departments of the current resource )


    Below is an example HTTP exchange (bodies are in yaml since it's easier to write):



    Request



    GET / HTTP/1.1
    Host: api.acme.io
    Accept: text/yaml, text/acme-mediatype+yaml


    Response: a list of links to main resource (companies, people, whatever...)



    HTTP/1.1 200 OK
    Date: Tue, 05 Apr 2016 15:04:00 GMT
    Last-Modified: Tue, 05 Apr 2016 00:00:00 GMT
    Content-Type: text/acme-mediatype+yaml

    # body: this is your API's entrypoint (like a homepage)
    links:
    # could be some random path https://api.acme.local/modskmklmkdsml
    # the only thing the API client cares about is the key (or rel) "companies"
    companies: https://api.acme.local/companies
    people: https://api.acme.local/people


    Request: link to companies (using previous response's body.links.companies)



    GET /companies HTTP/1.1
    Host: api.acme.local
    Accept: text/yaml, text/acme-mediatype+yaml


    Response: a partial list of companies (under items), the resource contains related links, like link to get the next couple of companies (body.links.next) an other (templated) link to search (body.links.search)



    HTTP/1.1 200 OK
    Date: Tue, 05 Apr 2016 15:06:00 GMT
    Last-Modified: Tue, 05 Apr 2016 00:00:00 GMT
    Content-Type: text/acme-mediatype+yaml

    # body: representation of a list of companies
    links:
    # link to the next page
    next: https://api.acme.local/companies?page=2
    # templated link for search
    search: https://api.acme.local/companies?query={query}
    # you could provide available actions related to this resource
    actions:
    add:
    href: https://api.acme.local/companies
    method: POST
    items:
    - name: company1
    links:
    self: https://api.acme.local/companies/8er13eo
    # and here is the link to departments
    # again the client only cares about the key department
    department: https://api.acme.local/companies/8er13eo/departments
    - name: company2
    links:
    self: https://api.acme.local/companies/9r13d4l
    # or could be in some other location !
    department: https://api2.acme.local/departments?company=8er13eo


    So as you see if you go the links/relations way how you structure the path part of your URLs does't have any value to your API client. And if your are communicating the structure of your URLs to your client as documentation, then your are not doing REST (or at least not Level 3 as per "Richardson's maturity model")






    share|improve this answer














    How your URLs look have nothing to do with REST. Anything goes. It actually is an "implementation detail". So just like how you name your variables. All they have to be is unique and durable.



    Don't waste too much time on this, just make a choice and stick to it/be consistent. For example if you go with hierarchies then you do it for all your resources. If you go with query parameters...etc just like naming conventions in your code.



    Why so ? As far as I know a "RESTful" API is to be browsable (you know..."Hypermedia as the Engine of Application State"), therefore an API client does not care about what your URLs are like as long as they're valid (there's no SEO, no human that needs to read those "friendly urls", except may be for debugging...)



    How nice/understandable a URL is in a REST API is only interesting to you as the API developer, not the API client, as would the name of a variable in your code be.



    The most important thing is that your API client know how to interpret your media type.
    For example it knows that :




    • your media type has a links property that lists available/related links.

    • Each link is identified by a relationship (just like browsers know that link[rel="stylesheet"] means its a style sheet or rel=favico is a link to a favicon...)

    • and it knowns what those relationships mean ("companies" mean a list of companies,"search" means a templated url for doing a search on a list of resource, "departments" means departments of the current resource )


    Below is an example HTTP exchange (bodies are in yaml since it's easier to write):



    Request



    GET / HTTP/1.1
    Host: api.acme.io
    Accept: text/yaml, text/acme-mediatype+yaml


    Response: a list of links to main resource (companies, people, whatever...)



    HTTP/1.1 200 OK
    Date: Tue, 05 Apr 2016 15:04:00 GMT
    Last-Modified: Tue, 05 Apr 2016 00:00:00 GMT
    Content-Type: text/acme-mediatype+yaml

    # body: this is your API's entrypoint (like a homepage)
    links:
    # could be some random path https://api.acme.local/modskmklmkdsml
    # the only thing the API client cares about is the key (or rel) "companies"
    companies: https://api.acme.local/companies
    people: https://api.acme.local/people


    Request: link to companies (using previous response's body.links.companies)



    GET /companies HTTP/1.1
    Host: api.acme.local
    Accept: text/yaml, text/acme-mediatype+yaml


    Response: a partial list of companies (under items), the resource contains related links, like link to get the next couple of companies (body.links.next) an other (templated) link to search (body.links.search)



    HTTP/1.1 200 OK
    Date: Tue, 05 Apr 2016 15:06:00 GMT
    Last-Modified: Tue, 05 Apr 2016 00:00:00 GMT
    Content-Type: text/acme-mediatype+yaml

    # body: representation of a list of companies
    links:
    # link to the next page
    next: https://api.acme.local/companies?page=2
    # templated link for search
    search: https://api.acme.local/companies?query={query}
    # you could provide available actions related to this resource
    actions:
    add:
    href: https://api.acme.local/companies
    method: POST
    items:
    - name: company1
    links:
    self: https://api.acme.local/companies/8er13eo
    # and here is the link to departments
    # again the client only cares about the key department
    department: https://api.acme.local/companies/8er13eo/departments
    - name: company2
    links:
    self: https://api.acme.local/companies/9r13d4l
    # or could be in some other location !
    department: https://api2.acme.local/departments?company=8er13eo


    So as you see if you go the links/relations way how you structure the path part of your URLs does't have any value to your API client. And if your are communicating the structure of your URLs to your client as documentation, then your are not doing REST (or at least not Level 3 as per "Richardson's maturity model")







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Aug 26 '16 at 16:11

























    answered Apr 5 '16 at 14:49









    redben

    3,79843559




    3,79843559








    • 6




      "How nice/understandable a URL is in a REST API is only interesting to you as the API developer, not the API client, as would the name of a variable in your code be." Why would this NOT be interesting? This is very important, if anyone but yourself is also using the API. This is part of the user experience, so I would say it is very important that this is easy to understand for the API client developers. Making things even more easy to understand by linking resources clearly is of course a bonus (level 3 in the url you provide). Everything should be intuitive and logical with clear relations.
      – Joakim
      Sep 11 '16 at 20:33






    • 1




      @Joakim If you are making a level 3 rest API (Hypertext As The Engine Of Application State), then the url's path structure is absolutely of no interest to the client (as long as it is valid). If you are not aiming for level 3, then yes, it is important and should be guessable. But real REST is level 3. A good article: martinfowler.com/articles/richardsonMaturityModel.html
      – redben
      Sep 11 '16 at 21:19






    • 3




      I object to ever creating an API or UI that is not user friendly for human beings. Level 3 or not, I agree linking resources is a great idea. But to suggest doing so "makes it possible to change URL scheme" is to be out of touch with reality, and how people use APIs. So it's a bad recommendation. But sure in the best of all worlds everyone would be at Level 3 REST. I incorporate hyperlinks AND use a humanly understandable URL scheme. Level 3 does not exclude the former, and one SHOULD care in my opinion. Good article though :)
      – Joakim
      Sep 11 '16 at 21:29










    • One should of course care for the sake of maintainability and other concerns, I think you miss the point of my answer : the way the url looks does not deserve a lot of thinking and you should "just make a choice and stick to it/be consistent" as I said in the answer. And in the case of a REST API, at least my opinion, user friendlyness is not in the url, it is mostly in (the media type) Anyway I hope you understand my point :)
      – redben
      Sep 11 '16 at 22:14
















    • 6




      "How nice/understandable a URL is in a REST API is only interesting to you as the API developer, not the API client, as would the name of a variable in your code be." Why would this NOT be interesting? This is very important, if anyone but yourself is also using the API. This is part of the user experience, so I would say it is very important that this is easy to understand for the API client developers. Making things even more easy to understand by linking resources clearly is of course a bonus (level 3 in the url you provide). Everything should be intuitive and logical with clear relations.
      – Joakim
      Sep 11 '16 at 20:33






    • 1




      @Joakim If you are making a level 3 rest API (Hypertext As The Engine Of Application State), then the url's path structure is absolutely of no interest to the client (as long as it is valid). If you are not aiming for level 3, then yes, it is important and should be guessable. But real REST is level 3. A good article: martinfowler.com/articles/richardsonMaturityModel.html
      – redben
      Sep 11 '16 at 21:19






    • 3




      I object to ever creating an API or UI that is not user friendly for human beings. Level 3 or not, I agree linking resources is a great idea. But to suggest doing so "makes it possible to change URL scheme" is to be out of touch with reality, and how people use APIs. So it's a bad recommendation. But sure in the best of all worlds everyone would be at Level 3 REST. I incorporate hyperlinks AND use a humanly understandable URL scheme. Level 3 does not exclude the former, and one SHOULD care in my opinion. Good article though :)
      – Joakim
      Sep 11 '16 at 21:29










    • One should of course care for the sake of maintainability and other concerns, I think you miss the point of my answer : the way the url looks does not deserve a lot of thinking and you should "just make a choice and stick to it/be consistent" as I said in the answer. And in the case of a REST API, at least my opinion, user friendlyness is not in the url, it is mostly in (the media type) Anyway I hope you understand my point :)
      – redben
      Sep 11 '16 at 22:14










    6




    6




    "How nice/understandable a URL is in a REST API is only interesting to you as the API developer, not the API client, as would the name of a variable in your code be." Why would this NOT be interesting? This is very important, if anyone but yourself is also using the API. This is part of the user experience, so I would say it is very important that this is easy to understand for the API client developers. Making things even more easy to understand by linking resources clearly is of course a bonus (level 3 in the url you provide). Everything should be intuitive and logical with clear relations.
    – Joakim
    Sep 11 '16 at 20:33




    "How nice/understandable a URL is in a REST API is only interesting to you as the API developer, not the API client, as would the name of a variable in your code be." Why would this NOT be interesting? This is very important, if anyone but yourself is also using the API. This is part of the user experience, so I would say it is very important that this is easy to understand for the API client developers. Making things even more easy to understand by linking resources clearly is of course a bonus (level 3 in the url you provide). Everything should be intuitive and logical with clear relations.
    – Joakim
    Sep 11 '16 at 20:33




    1




    1




    @Joakim If you are making a level 3 rest API (Hypertext As The Engine Of Application State), then the url's path structure is absolutely of no interest to the client (as long as it is valid). If you are not aiming for level 3, then yes, it is important and should be guessable. But real REST is level 3. A good article: martinfowler.com/articles/richardsonMaturityModel.html
    – redben
    Sep 11 '16 at 21:19




    @Joakim If you are making a level 3 rest API (Hypertext As The Engine Of Application State), then the url's path structure is absolutely of no interest to the client (as long as it is valid). If you are not aiming for level 3, then yes, it is important and should be guessable. But real REST is level 3. A good article: martinfowler.com/articles/richardsonMaturityModel.html
    – redben
    Sep 11 '16 at 21:19




    3




    3




    I object to ever creating an API or UI that is not user friendly for human beings. Level 3 or not, I agree linking resources is a great idea. But to suggest doing so "makes it possible to change URL scheme" is to be out of touch with reality, and how people use APIs. So it's a bad recommendation. But sure in the best of all worlds everyone would be at Level 3 REST. I incorporate hyperlinks AND use a humanly understandable URL scheme. Level 3 does not exclude the former, and one SHOULD care in my opinion. Good article though :)
    – Joakim
    Sep 11 '16 at 21:29




    I object to ever creating an API or UI that is not user friendly for human beings. Level 3 or not, I agree linking resources is a great idea. But to suggest doing so "makes it possible to change URL scheme" is to be out of touch with reality, and how people use APIs. So it's a bad recommendation. But sure in the best of all worlds everyone would be at Level 3 REST. I incorporate hyperlinks AND use a humanly understandable URL scheme. Level 3 does not exclude the former, and one SHOULD care in my opinion. Good article though :)
    – Joakim
    Sep 11 '16 at 21:29












    One should of course care for the sake of maintainability and other concerns, I think you miss the point of my answer : the way the url looks does not deserve a lot of thinking and you should "just make a choice and stick to it/be consistent" as I said in the answer. And in the case of a REST API, at least my opinion, user friendlyness is not in the url, it is mostly in (the media type) Anyway I hope you understand my point :)
    – redben
    Sep 11 '16 at 22:14






    One should of course care for the sake of maintainability and other concerns, I think you miss the point of my answer : the way the url looks does not deserve a lot of thinking and you should "just make a choice and stick to it/be consistent" as I said in the answer. And in the case of a REST API, at least my opinion, user friendlyness is not in the url, it is mostly in (the media type) Anyway I hope you understand my point :)
    – redben
    Sep 11 '16 at 22:14












    up vote
    5
    down vote













    I've read all of above answer but seem like have no common strategy. I found a good article about best practices in Design API from Microsoft Documents. I think you should refer.




    In more complex systems, it can be tempting to provide URIs that
    enable a client to navigate through several levels of relationships,
    such as /customers/1/orders/99/products. However, this level of
    complexity can be difficult to maintain and is inflexible if the
    relationships between resources change in the future. Instead, try to
    keep URIs relatively simple
    . Once an application has a reference to a
    resource, it should be possible to use this reference to find items
    related to that resource. The preceding query can be replaced with the
    URI /customers/1/orders to find all the orders for customer 1, and
    then /orders/99/products to find the products in this order.




    .




    Tip



    Avoid requiring resource URIs more complex than
    collection/item/collection.







    share|improve this answer



























      up vote
      5
      down vote













      I've read all of above answer but seem like have no common strategy. I found a good article about best practices in Design API from Microsoft Documents. I think you should refer.




      In more complex systems, it can be tempting to provide URIs that
      enable a client to navigate through several levels of relationships,
      such as /customers/1/orders/99/products. However, this level of
      complexity can be difficult to maintain and is inflexible if the
      relationships between resources change in the future. Instead, try to
      keep URIs relatively simple
      . Once an application has a reference to a
      resource, it should be possible to use this reference to find items
      related to that resource. The preceding query can be replaced with the
      URI /customers/1/orders to find all the orders for customer 1, and
      then /orders/99/products to find the products in this order.




      .




      Tip



      Avoid requiring resource URIs more complex than
      collection/item/collection.







      share|improve this answer

























        up vote
        5
        down vote










        up vote
        5
        down vote









        I've read all of above answer but seem like have no common strategy. I found a good article about best practices in Design API from Microsoft Documents. I think you should refer.




        In more complex systems, it can be tempting to provide URIs that
        enable a client to navigate through several levels of relationships,
        such as /customers/1/orders/99/products. However, this level of
        complexity can be difficult to maintain and is inflexible if the
        relationships between resources change in the future. Instead, try to
        keep URIs relatively simple
        . Once an application has a reference to a
        resource, it should be possible to use this reference to find items
        related to that resource. The preceding query can be replaced with the
        URI /customers/1/orders to find all the orders for customer 1, and
        then /orders/99/products to find the products in this order.




        .




        Tip



        Avoid requiring resource URIs more complex than
        collection/item/collection.







        share|improve this answer














        I've read all of above answer but seem like have no common strategy. I found a good article about best practices in Design API from Microsoft Documents. I think you should refer.




        In more complex systems, it can be tempting to provide URIs that
        enable a client to navigate through several levels of relationships,
        such as /customers/1/orders/99/products. However, this level of
        complexity can be difficult to maintain and is inflexible if the
        relationships between resources change in the future. Instead, try to
        keep URIs relatively simple
        . Once an application has a reference to a
        resource, it should be possible to use this reference to find items
        related to that resource. The preceding query can be replaced with the
        URI /customers/1/orders to find all the orders for customer 1, and
        then /orders/99/products to find the products in this order.




        .




        Tip



        Avoid requiring resource URIs more complex than
        collection/item/collection.








        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jun 19 at 2:25

























        answered Jun 19 at 2:15









        Long Nguyen

        1,31211322




        1,31211322






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f20951419%2fwhat-are-best-practices-for-rest-nested-resources%23new-answer', 'question_page');
            }
            );

            Post as a guest




















































































            Popular posts from this blog

            Guess what letter conforming each word

            Port of Spain

            Run scheduled task as local user group (not BUILTIN)