8

From Roy Fielding's comment on his own article decrying fake REST apis:

A truly RESTful API looks like hypertext. Every addressable unit of information carries an address, either explicitly (e.g., link and id attributes) or implicitly (e.g., derived from the media type definition and representation structure). Query results are represented by a list of links with summary information, not by arrays of object representations (query is not a substitute for identification of resources).

This means that if you needed to, say, query for a list of the 100 most recently logged in users, and display their names and emails, you'd need to first do a GET query for the list of results, which would (essentially) be a list of link elements, with each link object containing the URI of a user resource. You would then need to make 100 more GET requests -- one for each user resource -- before you'd actually have the data you need to display your results.

That seems incredibly inefficient. Is there really no other truly RESTful way to get the data you need in 1 or 2 requests?

  • 1
    Didn't you miss the part: "with summary information"? – Luc Franken Jul 20 '16 at 7:23
  • 1
    I didn't miss it, but "summary information" implies "summary" to me, not "all of the data." He specifically says "not by arrays of object representations" -- which is exactly what we need for our display. – Jonah Jul 20 '16 at 7:29
  • 1
    We see the list as a resource and for us it contains fields like: link to single resource, title, short description and # of comments for example. We don't include full objects because they are way too big. So our list resources fully supply all info needed to use it. When you want more you load the full resource which may include forms, lots of content and other bigger parts. We tried once to include all resources (YAGNI process of thinking) in full but that broke down. So we added this step. And I think it's fully REST, a list of info is a resource on its own. – Luc Franken Jul 20 '16 at 7:36
  • Don't try to strictly apply (blindly) Fielding sentences about REST. Of course he is the father of REST architecture, but be careful: REST architecture is for high scalable systems, that's why it has been inferred from the web. If it makes sense to use an array of object for performance issue, then go for it. – AilurusFulgens Jul 20 '16 at 9:48
  • HAL+json is generally considered to be RESTful. It includes both a slimmed down version (summary) of the objects plus a link to the full resource. – RubberDuck Jul 21 '16 at 1:38
7

Is there really no other truly RESTful way to get the data you need in 1 or 2 requests?

  • Not really
  • But don't over think it

As usual, when thinking about REST, keep in mind that there is a reference implementation (the world wide web) that you can check against.

Consider the Amazon portal - when I open that bookmark with an empty cache, I see my browser make requests to 275 resources.

Would I get better latency if all of that state were fetched in a single payload? Yes.

Would it scale? would it web-scale? Probably not. That's 4.5MB of data that can't be shared because in includes 1KB that is specific to my profile. If my colleague at the desk next to me also goes to Amazon, she pulls the same data across the network.

Decompose that payload into individually addressable resources, and suddenly things get a lot better -- we each still get our 1KB of personalization, and we each still have our locally cached copy of the 4.5MB, but we haven't needed to bang the network as hard, because most of our requests were served by a local shared cache, rather than needing to route across the internet.

Also, keep in mind that you don't really have an issue with multiple resources, you have an issue with multiple requests. That can be mitigated using HTTP/2.0 Push Promises, with the server proactively pushing representations that can be cached. Maybe - a stateless server doesn't know what the client has cached, and TLS suggests that caching at intermediates isn't a priority....

This means that if you needed to, say, query for a list of the 100 most recently logged in users, and display their names and emails, you'd need to first do a GET query for the list of results, which would (essentially) be a list of link elements, with each link object containing the URI of a user resource. You would then need to make 100 more GET requests -- one for each user resource -- before you'd actually have the data you need to display your results.

Of course, if you were doing this in html, your representation of the most recently logged in users would probably be a document with a list or a table of names and email addresses and links to those resources. Ta-da.

Don't lose track of this observation by Fielding.

That doesn’t mean that I think everyone should design their own systems according to the REST architectural style. REST is intended for long-lived network-based applications that span multiple organizations. If you don’t see a need for the constraints, then don’t use them.

EDIT

can i make the same argument for a JSON representation? ie, if the resource in question is "100 last logged in users" rather than results of a parameterized query, can i then return the data itself instead of resource links? if not, why? why is JSON essentially different from HTML in this regard?

How they are alike: packing more data into the "list of results" saves you the costs of the additional requests, while compromising scaling. The specific media type you are using for the representation doesn't matter -- at least, as far as I know.

How they are different: HTML is a hypermedia format, and JSON isn't -- any bog standard client implementation that is familiar with the HTML spec will know how to find the links in an HTML document, which supports options like pre-fetching. JSON doesn't have that standardization - you need out-of-band information about the data structure to understand where the links are in a JSON representation. HAL would be a closer match to HTML in this regard; the primary difference between HAL and HTML is adoption; HTML has a 20 year head start?

For additional insights, you might also consider reviewing the Atom Syndication Format, which describes both Entries and Feeds (lists of Entries), especially the rules for atom:entry, which might be accessed via a stand alone resource, or via a feed resource.

  • 1
    That last paragraph by Fielding should be stenciled on the foreheads of all of the REST pedants in reverse text, so that they can see it every time they look in the mirror. – Robert Harvey Jul 20 '16 at 15:41
  • great answer as usual. re: your last paragraph on an HTML representation, can i make the same argument for a JSON representation? ie, if the resource in question is "100 last logged in users" rather than results of a parameterized query, can i then return the data itself instead of resource links? if not, why? why is JSON essentially different from HTML in this regard? – Jonah Jul 20 '16 at 15:50
  • @Jonah JSON is not a hypermedia format, at the opposite of HTML (and some others). An hypermedia format allow to describe links and relations. In HTML you do this with <a href="URI" rel=""> and <form method="post"> for example. In JSON you cannot, unless you use it in an ad hoc way, because JSON does not define anything about hypermedia (some example of ad-hoc hypermedia usage in JSON: _link : [ ... ] , links : [ ... ] , _link_ : [ ... ], etc.) (PS: great answer) – AilurusFulgens Jul 20 '16 at 17:04
  • @AilurusFulgens, sure, i should have been more specific. i meant something like "hal+json" (or any other JSON-based hypermedia format) -- the thrust of the question is the same: why is it okay to return a "document" in HTML with all of the data, but not do the same in a JSON-based hypermedia format? – Jonah Jul 20 '16 at 17:49
  • thanks for the edit. so to make sure I understand you, if you returned all the results in an HTML table, rather than say a <ul> of clickable links, you would be compromising scaling just as much as if you did the equivalent in a hal+json response? specifically, such a response would not scale as well because the results returned, which presumably change often, won't be cachable? whereas a list of links is less data, so the uncachable part is smaller? is that the idea or is there more i'm missing? – Jonah Jul 21 '16 at 6:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.