When reading through "REST API Best Practices", it is often recommended to name resources by hierarchy, like this:
https://api.example.com/projects/{projectid}/documents/{documentid}
Now I would like to name resources by a path which can have any depth so that a resource (like a project) could be located like this:
https://api.example.com/projects/{group}/{projectname}
or
https://api.example.com/projects/{group}/{subgroup}/{projectname}
But now naming resources by hierarchy is ambiguous, because:
https://api.exmaple.com/projects/mygroup/mysubgroup/projectname/documents/document1
Could refer to the project document1
in the path /mygroup/mysubgroup/projectname/documents/
, which is not correct.
Also actions on a project, like:
https://api.exmaple.com/projects/mygroup/mysubgroup/projectname/edit
Have the same problem.
What would be a RESTful way of dealing with resources named by path that have a hierachy?
What would be a RESTful way of dealing with resources named by path that have a hierarchy?
REST is an architectural style and not a cookbook for designing URIs (see notes below). REST doesn't enforce any URI design and it's totally up to you to pick the URIs that better identify your resources.
While long URIs do the job when it comes to resource identification, sending multiple path parameters may be cumbersome for your clients. So you may want to consider short URIs:
/documents/{id}
/projects/{id}
/groups/{id}
Short URIs are easier to remember and you always can use query parameters to filter the resources.
Note 1: The URI syntax is defined in the RFC 3986. As general rule, the path is organized in hierarchical form (with segments separated by /
) and can contain non-hierarchical data in the query component (starting with ?
).
Note 2: The REST architectural style is described in the chapter 5 of Roy T. Fielding's dissertation and it defines a set of constraints that must be followed by the applications that follow such architecture. However it says nothing about what the URIs must be like.
Note 3: The examples of a popular article written by Martin Fowler explaining a model defined by Leonard Richardson suggest a URI structure that looks friendly and easy to read.
I think this question can not be answered, just discussed.
For a CRUD application, consider using flat pathes with a unique id (URI) for each resource.
/groups/:id
/documents/:id
/projects/:id
Then relate your entities like needed and add additional endpoints for queries.
Example:
/search?group=id&subgroup=id&document=id&project=id
In a more advanced REST approach the HTTP-Path is more independent from the resource itself. By sending an HTTP request you're asking about a certain representation of 'some' resource. This is not only expressed by the path, but also by the media type (send in HTTP header). Your client could call...
GET -H"accept:application/vnd.myapi.subgroup" /documents/document1
...which may result in a different response than
GET -H"accept:application/vnd.myapi.document" /documents/document1