Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RESTful API routes design: nested vs. non-nested

Tags:

My question is about the advantages of nesting resources when building URLs for API purposes. Consider the following two alternatives for accessing an employee resource:

/api/employees?department=1   # flat  Vs.  /api/departments/1/employees  # nested 

Now consider the task of developing a general purpose library to access REST resources from an API. If all routes were flat, such a REST wrapper library would only need to know the name of the resource being accessed:

store.query('employees', {department_id:1})   =>   /api/employees?department=1 

However, if we were to support nested routes, this wrapper would need to know extra information about what models are nested and under which other resource, in order to know how to build the URLs for referencing such a model. Given that not all models would be nested under the same parent resource, and even some models would not be nested at all, the REST wrapper library would need to have some sort of configuration describing all this extra knowledge that wouldn't be needed otherwise.

So my questions are:

  • Are there any real advantages to nested resource routes in an API? (Which is not meant to be consumed by end users, and therefore gains less from having prettier URLs).

  • Is the nested approach really better than flat, beyond aesthetics, so as to justify the extra effort and complexity introduced to support the lack of uniformity in resource URL building?

See also: https://stackoverflow.com/a/36410780/621809

UPDATE: IMPORTANT CLARIFICATION

I realize from some of the comments and answers, that I wasn't clear enough regarding one aspect: I'm not against addressing single resources with URLs like /employees/5 or /departments/1. I don't consider that to be nested.

When I say nested resources, I refer to URLs like /departments/1/employees where a resource is addressed always within the context of another resource. The main issue is the fact that for URL building, a generic library would need to know extra stuff like "employees are nested under departments" but "branches are not nested under anything". If all resources could be addressed RESTfully, but in a flat fashion, it is simpler and more predictable to know how to address them.

When you think about it, in databases you don't need to know extra information in order to know how to address a collection of objects (e.g. a table in a RDMS). You always refer to the collection of employees as employees, not as departments/5/employees.

like image 464
Ernesto Avatar asked Aug 27 '16 04:08

Ernesto


People also ask

What are the 3 components of a RESTful API?

A REST message contains these components: Resource Path. HTTP Verb. Body.

How many RESTful routes are there?

There are 7 different restful routes pattern to follow when creating an application or web service that will interact with the server.

What are nested resources?

Nesting resources provide REST API consumers an easy and efficient way to manage data by allowing the consumer to send and receive only the required object. The nested resource must be a business object, that is, it must still represent a complete business object.


2 Answers

What happens if you want do drill down a couple more levels?

/api/addresses?departmentId=1&employeeId=2&addressId=3

vs

/api/departments/1/employees/2/addresses/3

The Address endpoint suddenly becames bloated with parameters.

Also, if you're looking at the Richardson Maturity Model level 3, RESTful APIs are meant to be discoverable through links. For example, from the top level, say /api/version(/1), you would discover there's a link to the departments. Here's how this could look in a tool like HAL Browser:

"api:department-query": {   "href": "http://apiname:port/api/departments?pageNumber={pageNumber}&pageSize={pageSize}&sort={sort}" }, "api:department-by-id": {   "href": "http://apiname:port/api/departments?departmentId={departmentId}" } 

(either a query that might list them all, in a paged manner eventually, or a parameterized link that would go directly to a specific department, provided you know the id).

The advantage here would be that the client would only need to know the relationship (link) name, while the server would be mostly free to alter the relationship (and resource) url.

like image 148
Alexandru Marculescu Avatar answered Sep 27 '22 23:09

Alexandru Marculescu


Old post, but not satisfactory answer for me.

It depends on your API. If your data is hierarchical and do not need to access resources without filtering them by their parents, then nested is OK (and not nested too).

If your ids are long (GUIDs), your hierarchy is deep, or you need to access any resource without filtering by its parents then not nested is a good option.

Try to have a unified interface and not having many ways for accessing the same resource.

Try this link that explains this a lot better: https://www.moesif.com/blog/technical/api-design/REST-API-Design-Best-Practices-for-Sub-and-Nested-Resources/

like image 23
Dodger Avatar answered Sep 27 '22 23:09

Dodger