I just wanted to address a couple points that might have been fuzzy.
If nothing else, it is just more information to make our decision...

On Feb 20, 2013, at 12:11 AM, Heiko W.Rupp <hrupp@redhat.com> wrote:

Hi Mike,

thanks for writing that lengthy email.

Am 20.02.2013 um 03:30 schrieb mike thompson:

For me, the #2 method (placing paging in the body) is advantageous for clients as they can just marshal the document body and get at the paging information via normal ways. The other advantage is that all the state (prev and next are alternate states for page results) is contained within the body. No need for the client to look up in the header to and figure out the format to parse the object in the header (and also know the key name for the header object). This all creates unneccessary work for the client when marshalling is pretty much automatic (like with JSON and Javascript).

You also need to know the name of the Link object in the body - besides, the header "Link:" is standard, so there is no guessing.
If you marshall into e.g. Java objects you also need to have a specialized class that has sub-elements for paging and the real payload.
Or you marshall into a generic map and try to find the paging objects by their name.
You don't need to know the Link name for the marshaling when it is in the body. Only when you go to use it -- at some point you need to know the name. But, you do need to know the link name in the header just to extract it because it doesn't get marshaled with the body.



How parsable is this format?

Link: <http://foo/?page=3>; rel='next'
Link: <http://foo/?page=1>; rel='prev'

This concrete format is out, as I have stated in the update to my blog post, because URLConnection.getHeaderField() can not deal with it.
That leaves

  Link: <http://foo/?page=3>; rel='next', <http://foo/?page=1>; rel='prev'


It looks like a combination of formats that definately requires custom parsing on the client side. I realize it is RFC 5988, but you would think they could pick a more
consistent(parser friendly) format. Any idea how prevalent this is? I did a search and couldn't find much but maybe I'm not aware of the right resources. I see that it was

I do not think it makes sense to invent an own format. RFC 5988 is an accepted format.
Certainly, I'm not suggesting our own custom format. Placing in the body is a Standard (just look at Atom). Using just standard attributes in either XML or JSON.

<customers>

<link rel="next" href="http://example.com/customers?start=2&size=2" type="application/xml"/>

<customer id="123"> <name>Bill Burke</name>

</customer> <customer id="332">

<name>Roy Fielding</name> </customer>

</customers> 


a 'Proposed Standard' in 2010  [http://datatracker.ietf.org/doc/rfc5988/] but not much activity since then. This deserves more research time than I can give it but does raise an eyebrow.

So you are saying, the internet can not rely on SMTP email transport, because RFC822 did not change since 1982? :-)
The fact alone that RFC 5988 is published as a RFC makes it a standard, as this means that it went through a series of ietf-drafts before being accepted
as RFC.
RFC 5988 just isn't necessary with links in the body. <Tangent> And why did they choose the format they did? It looks like multiple formats. Why not a consistent format like json that is easily consumed by browsers without any library tooling (this "Standard" was created in 2010, they should know better)</Tangent>
I did see your message stating that JAX RS 2.0 has Link parser in it -- which is great.
Here is an example of JSON links in the body that the browser via javascript (and any JSON lib for other languages) knows how to marshal into objects.
{

"link" : {

"rel" : "alternate",

"href" : "http://east-nj1.photos.example.org/987/nj1-1234", }

}

{
"links" : [

{
"rel" : "alternate",

"href" : "http://east-nj1.photos.example.org/987/nj1-1234

},

{
"rel" : "http://www.example.org/rels/owner",

"href" : "http://east-nj1.photos.example.org/987",

 }

]

 } 

Consistent, simple attributes.

And for parsing I guess in almost all languages other than java, this can be expressed in two lines :)
But then parsing { 'paging' : [ { "url":"http://foo...","rel":"next"},{....}]} is not obvious either.

One big argument against adding the paging info to the body for me is that for all clients that are out there,
adding the paging info in the body will break them.
To stay backwards compatible we would already need to generate custom media types for paging.
I developed large RESTful apps before that didn't break when adding new elements. [I must not be thinking of the same circumstances.]


For those not familiar with HATEOAS, here is Bill Burke's definition for java developers:
"I’ve explained HATEOAS with this analogy to Java developers. Imagine, a Java Swing app passing value objects to a remote Hibernate service and merging the changes. Instead of Java objects are your value objects, think of XML or JSON. Now add the idea of embedding links into your XML or JSON that tell you where you can edit the service that represents these value objects, or links to other services related to this data."

If you look at the RestEasy documentation, Bill very much supports the Link: headers
Very True, this is a big pro for the issue. Although, I can point to others such as "Dr REST" Subbu Allamaraju, author of "Restful Web Services Cookbook" that disagrees with this and states that:

Link headers are appropriate in the following cases:

  • Representations that use binary format, such as images, rich-text documents, spreadsheets, etc.

  • Representations in formats that do not allow the easy discovery of links (e.g., plain- text documents)

  • When your client/server software needs to add links or read links without parsing the body of representations 


Leaving everything in the body also sets a better precedent for state other than paging (HATEOAS) that should go into the doc body. HATEOAS is an essential part of

This argument is totally bogus, as e.g. the media type is not selected in the body, but via header
The context of "everything" is the paging stuff. Its silly to think "everything" goes into the body. I should be more careful with my words. Yes. Media types are selected in the header.

REST and its use should be encouraged. REST representations are meant to support alternate states and allow for easy discoverability by the client. The

And you request the representations via header field.
Totally Agree.

encapsulated states sent to the client make for less logic on the client (meaning less brittle client applicatons). For instance, encapsulated states can be sent to the client to provide state machines or validation rules and cached by the client, cutting down the number of round trips to the server.

That is all correct what you say, but has no effect on the placement of the paging headers.

Pragmatically, the way our REST APIs will be used is primary via CL/I(javascript) so not having to reach into the header and parse pagnation data will make much simpler/powerful integration scripts for our customers (IMO).

What makes you think this is true? We have an Android app, that works via REST-api - adding the paging stuff to the body breaks that app
It will also break all the examples that we have that return collections. How does adding the paging to the body make those existing clients
less brittle?
I don't consider adding elements to a document as a breaking change. Changing or deleting existing elements yes, but add new elements no. This can also be easily fixed with a versioning strategy that should exist anyway. 

I do believe the header is a good place to store non-state data that is not dependent on the on the body or relates to the body. Self describing meta-data comes to

Paging links are not state representations of objects - switching a page does not modify the objects.
While not the state of your object it is the state of your collection (i.e., where you are in your collection and the possible paths to other states: next, prev, first, last)

We will probably want to add self, first and last to prev/next regardless of the outcome of where to put this data. Also useful, would be record counts and/or page
counts. Record counts via HEAD could provide client with insight as to whether or not they should retrieve resources via a GET.

Right. I have already added the page count and may add the others too.
Excellent!

A client starts from the first page, and then through the link on that page, goes to the second page. The fact that this page has one link to the first page and another to the third page implies that the current state of the application (i.e. the interactions) is that "the client is viewing the second page". That is what it means by hypermedia as the engine of application state. It does not necessarily mean serializing application state, such as "<page>2</page>" into representations."

Yes totally. Which is what we largely do already.

 Heiko

The biggest 'con' to the in body pagination is with media types  other than json or xml (like csv or jpg); although some would call those corner cases.

I think the final take away is there is not a single "standard" way of doing RESTful pagination. There are a couple methods depending on your objectives.
http://stackoverflow.com/questions/9742380/link-headers-vs-link-elements-for-restful-json?rq=1

For me, having pagination in the body, is a pure REST approach that doesn't need any tooling; so it supports more languages/technologies easier. The paging in the header technique will also work well, but needs API support to make the paging transparent to the user.
If we do use the header technique. We need to be sure to include the pagination header parsing javascript in our CL/I javascript module for client convenience.

Thanks for hearing me out,

Mike



_______________________________________________
rhq-devel mailing list
rhq-devel@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/rhq-devel