Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RESTFul Flat Hierarchy vs. Dynamic Hierarchy for Search Resource

We are creating a REST API and we currently have two approaches for defining the resources.

Basically we have Patients, Studies and Images where a Patient has n Studies and a Study has n Images.

Hierarchical Approach

/webapi/patients/0/studies/12/images 

The hierarchy is visible in the URI

To search for all images we would need a search resource

 /webapi/search?q=imageName:mountain

Flat Approach

/webapi/patients/0
/webapi/studies/12
/webapi/images/

The hierarchy is done by an attribute (for example study 12 has a patientIdof 0).

To search for all images we can search on the resource itself:

 /webapi/images?q=imageName:mountain

Is there a best practice approach or does anyone have experienced a similar scenario? Is a search resource REST or is it bad that the relation from an image is not visible in the flat approach.

Also we need to think about move and modification.

like image 973
sandrozbinden Avatar asked Sep 16 '14 15:09

sandrozbinden


2 Answers

Flat and hierarchical URIs could be both RESTful. The problem is elsewhere. Being RESTful suppose that URIs are identifiers of resources.

What resource is identified by /wepapi/patients/0/studies/12/images? The images of studies 12.

Is it really a bad identifier? Not really.

Could it be better? Definitely:

  • wepapi (the way you get a representation of the resource) has nothing to do with the abstract resource. The most RESTful approach would be to have the same URI for different concrete "representations" of the same abstract resource (see HTTP Accept headers for more information).
  • patients/0is not needed to identify those images. You might think that it would be cool for client software to get this datum by parsing the URI, but... they are not supposed to do that. URI are said to be "opaque".

What resource is identified by /search?q=imageName:mountain? The images that are named "mountain".

Is it really a bad identifier? Not really. Could it be better? Definitely:

  • search looks like a verb, which should raise a lot of warnings in a RESTful designer mind. In a way, we could say that the URI identify "a search" or "search results" (a noun and not a verb), but it is safer to consider that it identifies "images".

Last but not least, choosing between /studies/12/images and /images/?studies=12 in order to be "coherent" with either /studies/12 or /images/?name=mountain is purely a software design choice. Take the solution that will be the more elegant for your application. It has nothing to do with REST, since URIs are not supposed to be hacked (remember, they are supposed to be "opaque"). The links between URIs are in their representations (JSON, XML, HTML...), not in their structure.

like image 87
Aurélien Avatar answered Jan 27 '23 01:01

Aurélien


As Aurélien pointed out designing the URI structure is not a REST concern. You should follow the URI standard, which is very loose. For example it states that the path is the hierarchical and the query is the non-hierarchical part of the URIs. The uniform interface constraint of REST is about using standard solutions, and there is no such a standard as nice URIs, so from a REST perspective it does not matter how you construct your URIs, because they won't be parsed by the client (unless you use URI templates for templating purposes).

According to the HATEOAS constraint your client has to follow hyperlinks sent by the service. Those hyperlinks must be annotated with metadata regarding the semantics of them. That metadata can be any kind of linked data. Currently IANA link relations are the most typical (by non-RDF formats), but you can use schema.org actions, etc... (by RDF formats) as well. So the clients check the metadata of the links, and does not care about the URI structure.

The nice URI structure is important only for the service developer. It is important because of 2 things:

  • It makes routing easier: you can map endpoints to controllers much easier if the URI is readable.
  • You can check that you mapped your URIs to resources and not to operations. If your cannot clear every single verb from the URI, then something is wrong. For example by POST /users/123?update=true&partial=true body you cannot remove the update. So possibly the HTTP method is wrong, because verbs go to there: PATCH /users/123 body solves the problem. Most of the verbs can be reduced to the standard HTTP methods, like GET, POST, PUT, DELETE, PATCH, etc... so in practice you (almost) never need a new method.

In my opinion the flat approach is better, because it's easier to parse. By finding things you usually rely on a single id, and not multiple ids.

/wepapi/patients/0/studies/12/images - This makes sense, because you are looking for images from the 12th study of the 0th patient. An alternative approach is /images?patient=0&study=12 or if the studies have a unique id, then /images?study=0_12. Btw. designing ad-hoc search queries is not the mostly elaborated part of REST. With simple queries you can manage it using the query part of the URIs.

REST is not something you can currently learn from practice. Most ppl never read or understood the theory, so there are a lot of flawed tutorials out there. You probably have to start with the Fielding dissertation and some additional dissertations, for example this one. There are a lot of interesting and potentially useful projects still under development, like Hydra, RESTdesc, etc. So REST implementations are far from an elaborated technology. We probably need another 15 years, or more...

like image 37
inf3rno Avatar answered Jan 27 '23 01:01

inf3rno