5

How would you model a resource that can have two different representations. For example, one representation may be "thin" withe most of its related resources accessible by links. Another representation may be "fat" where most of its related resources are embedded. The idea being, some clients don't mind having to make many calls to browse around the linked resources, but others want to get the data all at once.

Consider a movie resource that is associated with a director, actors, etc. Perhaps the thin version of it has the movie title only, and to get the data for the director, list of actors, etc., one must make additional requests via the embedded links to them. Perhaps the fat version of it contains all the movie nested inside, including the director's data, the data for the various actor's, etc.

How should one model this?

I see a few options:

  1. these two representations are really two different resources and require different URIs
  2. these two representations are in fact the same resource, and you can select between the two representations via custom media types, for example application/vnd.movie.thin+json and application/vnd.movie.fat+json.
  3. these two representations are in fact the same resource, and selecting the different representations should be done with query parameters (e.g. /movies/1?view=thin).
  4. Something else...

What do you consider the proper approach to this kind of API?

SingleShot
  • 18,821
  • 13
  • 71
  • 101
  • How about a query parameter such as `?view=fat` or `?view=thin`? I wouldn't go with playing with custom media types because it might not work in all the browsers. – laurent May 13 '14 at 02:33
  • Hmmm. I'm not sure if it fits REST but I will add it as another option to my question. – SingleShot May 13 '14 at 03:13
  • 1
    possible duplicate of [REST API having same object, but light](http://stackoverflow.com/questions/7846900/rest-api-having-same-object-but-light) – Will Hartung May 13 '14 at 03:44
  • Certainly high overlap but not duplicate. The linked question is only about query parameters. – SingleShot May 13 '14 at 16:09

3 Answers3

6

You could use the prefer header with the return-minimal parameter.

Community
  • 1
  • 1
Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
2

I prefer using Content-Type for this. You can use parameters, too:

application/vnd.myapp; profile=light

Doug Moscrop
  • 4,479
  • 3
  • 26
  • 46
1

The Fielding dissertation about REST tells you about the resource interface, that you have to bind your IRIs to resources, which are entity sets. (This is different from SOAP, because by there you usually bind your IRIs to operations.)

According to Darrel Miller, the path is for describing hierarchical data and the query string is for describing non-hierarchical data in IRIs, but we use the path and the query together to identify a resource inside an API.

So based on these you have two approaches:

  • You can say, that the same entity with fewer properties can be mapped to a new resource with an own IRI. In this case the /movies/1?view=thin or the /movies/1/view:thin is okay.
    Pros:
  • According to the RDF a property has rdf:type of rdf:Property and rdfs:Resource either, and REST has connections to the semantic web and linked data.
  • It is a common practice to create an IRI for a single property, for example /movies/1/title, so if we can do this by a single property, then we can do this by a collection of properties as well.
  • It is similar to a map reduce we already use for collection of entites: /movies/recent, etc... The only difference, that by the collection of entities we reduce a list or ordered set, and by the collection of properties we reduce a map. It is much more interesting to use the both in a combination, like: /movies/recent/title, which can return the titles of the recent movies.

Cons:

  • By RDF everything has an rdf:type of rdfs:Resource and maybe REST does not follow the same principles by web documents.

  • I haven't found anything about single properties or property collections can be or cannot be considered as resources in the dissertation, however I may accidentally skipped that section of the text (pretty dry stuff)...

  • You can say that the same entity with fewer properties is just a different representation of the same resource, so it should not have a different IRI. In this case you have to put your data about the preferred view to somewhere else into the request. Since by GET requests there is no body, and the HTTP method is not for storing this kind of things, the only place you can put it are the HTTP headers. By long term user specific settings you can store it on the server, or in cookies maintained by the client. By short term settings you can send it in many headers. By the content-type header you can define your own MIME type which is not recommended, because we don't like having hundreds of custom MIME types probably used by a single application only. By the content-type header you can add a profile to your MIME type as Doug Moscrop suggested. By a prefer header you can use the return-minimal settings as Darrel Miller suggested. By range headers you can do the same in theory, but I met with range headers only by pagination.
    Pros:

  • It is certainly a RESTful approach.

Cons:

  • Existing HTTP frameworks not always support extracting these kind of header params, so you have to write your own short code to do that.
  • I cannot find anything about how these headers are affecting the client and server side caching mechanisms, so some of them may not be supported in some browsers, and by servers you have to write your own caching implementation, or find a framework which supports the header you want to use.

note: I personally prefer using the first approach, but that's just an opinion.

According to Darrel Miller the naming of the IRI does not really count by REST.

You just have to make sure, that a single IRI always points to the same resource, and that's all. The structure of the IRI does not count by client side, because your client has to meet the HATEOAS constraint if you don't want it to break by any changes of the IRI naming. This means, that always the server builds the IRIs, and the client follows these IRIs it get in a hypermedia response. This is just like using web browsers to follow link, and so browse the web... By REST you can add some semantics to your hypermedia which explains to your client what it just get. This can be some RDF vocabulary, for example schema.org, microdata, iana link relations, and so on (even your own application specific vocab)...
So using nice IRIs is not a concern by REST, it is a concern only by configuring the routing on the server side. What you have to make sure by REST IRIs, that you have a resource - IRI mapping and not an operation - IRI mapping, and you don't use IRIs for maintaining client state, for example storing user id, credentials, etc...

Community
  • 1
  • 1
inf3rno
  • 24,976
  • 11
  • 115
  • 197
  • 2
    Both path and query identify the resource. There is no distinction. Media types can be used to describe precise semantics - vcard, activity stream, atom, text/url-list, etc, etc. The goal is not to design a media type that can only be used for one api. – Darrel Miller Jun 20 '14 at 04:04
  • "oth path and query identify the resource. There is no distinction." - Ohh sure there is. For example: `/users?id=1` will return a collection representation of the `/users` having a single item: `id=1` and `/users/1` will return an item representation of `/users/1`. Both do map reduce, but the query is about the current representation, and the path is about the resource itself. At least in most of the articles I read about REST until now (I cannot remember a single one which did it otherwise, but I am open). "The goal is not to design a media type that can only be used for one api." - Yes. – inf3rno Jun 20 '14 at 10:42
  • 1
    In the URI specification http://tools.ietf.org/html/rfc3986#page-23 it says... "The query component contains non-hierarchical data that, along with data in the path component (Section 3.3), serves to identify a resource within the scope of the URI's scheme and naming authority (if any)." The reason for the confusion is that an earlier version of the URI specification was poorly written leading people to believe that only the path identified the resource. – Darrel Miller Jun 20 '14 at 13:39
  • 1
    If we are talking REST, `/users?id=1` could return a picture of your grandmother's cat. Without knowing the link relation type of that URI and the content-type of the response, you do not know and can not know, as it would create URI space coupling between client and server. That's what the self-descriptive constraint is designed to prevent. – Darrel Miller Jun 20 '14 at 13:41
  • I checked the http://www.ics.uci.edu/~fielding/pubs/dissertation/evaluation.htm#sec_6_3_2 , but I found only about the self-descriptive constraint, that the HTTP messages should be self descriptive, so the HTTP server and the client both can automatically parse them using the content-type header. There is nothing about how to process the content of those messages after the parsing and nothing about the semantics of the messages... So can you please elaborate on what IRI naming has to do with the self-descriptive constraint? – inf3rno Jun 27 '14 at 02:04