RESTful API - Designing sub-resources

Rafa picture Rafa · Oct 13, 2016 · Viewed 14.9k times · Source

I am designing a RESTful API and I came up with a problem related to sub-resources.

I see other APIs using full URL to operate over sub-resources. Take the example where Company has Departments and Department has Employees.

In the beginning I though about implementing all possible URLs. Resulting on the following:

Approach A

01. ### COMPANY URLS ###
02. DELETE /companies/{companyId}
03. GET    /companies/{companyId}
04. POST   /companies
05. PUT    /companies/{companyId}
06. 
07. ### DEPARTMENT URLS ###
08. DELETE /companies/{companyId}/departments/{departmentId}
09. GET    /companies/{companyId}/departments/{departmentId}
10. POST   /companies/{companyId}/departments
11. PUT    /companies/{companyId}/departments/{departmentId}
12. DELETE /departments/{departmentId}
13. GET    /departments/{departmentId}
14. PUT    /departments/{departmentId}
15. 
16. ### EMPLOYEE URLS ###
17. DELETE /companies/{companyId}/departments/{departmentId}/employees/{employeeId}
18. GET    /companies/{companyId}/departments/{departmentId}/employees/{employeeId}
19. POST   /companies/{companyId}/departments/{departmentId}/employees
20. PUT    /companies/{companyId}/departments/{departmentId}/employees/{employeeId}
21. DELETE /departments/{departmentId}/employees/{employeeId}
22. GET    /departments/{departmentId}/employees/{employeeId}
23. POST   /departments/{departmentId}/employees
24. PUT    /departments/{departmentId}/employees/{employeeId}
25. DELETE /employees/{employeeId}
26. GET    /employees/{employeeId}
27. PUT    /employees/{employeeId}

As you can see, there are many URLs which do the same thing. Example: 08 is duplicated of 12; 09 is duplicated of 13; 17 is duplicated of 21 and 25...

I want to remove the duplication but keep consistency. So, re-designed the API with a principle in mind sup-resources are fine but sub-sub-resources are not. Which resulted on the following:

Approach B

01. ### COMPANY URLS ###
02. DELETE /companies/{companyId}
03. GET    /companies/{companyId}
04. POST   /companies
05. PUT    /companies/{companyId}
06. 
07. ### DEPARTMENT URLS ###
08. DELETE /departments/{departmentId}
09. GET    /departments/{departmentId}
10. GET    /companies/{companyId}/departments
11. POST   /companies/{companyId}/departments
12. PUT    /departments/{departmentId}
13. 
14. ### EMPLOYEE URLS ###
15. DELETE /employees/{employeeId}
16. GET    /employees/{employeeId}
17. GET    /departments/{departmentId}/employees
18. POST   /departments/{departmentId}/employees
19. PUT    /employees/{employeeId}

My Questions

Q1. Is Approach B considered RESTful? (I am assuming yes)

Q2. Are there pitfalls Approach B I should consider, assuming that documentation is also provided?

Bonus points if you point to other APIs following Approach B.

EDIT

Elad Tabak presented good insights.

I fond some API using Approach B:

https://developers.google.com/youtube/v3/docs/

https://developer.github.com/guides/getting-started/

https://dev.twitter.com/rest/public

Answer

cassiomolin picture cassiomolin · Oct 13, 2016

Both approaches can be considered RESTful, provided you do not break the REST constraints defined in the chapter 5 of Roy Thomas Fielding's dissertation:

I cannot see major pitfalls in both approaches, but I would prefer the Approach B over the Approach A: the URLs are shorter, easier to remember and not many parameters are required.


Bonus points: Spotify and Facebook APIs follow this approach. For sure there are other APIs, but these are the ones that came up to my mind.