Re: Pagination (ISSUE-42)

Many thanks Dietrich, I believe you're making some progress that starts to
address some of my concerns.

Comments inline...

On 16 Feb 2015 19:48, "Dietrich Schulten" <ds@escalon.de> wrote:
>
> Hi,
>
> I want to re-phrase my proposal because my previous attempt appears to
> cause misunderstandings.
>
> This is not only a reply to Andrew, I'd like to ask everybody to
> consider my proposal.
>
> Am 15.02.2015 um 13:37 schrieb Andrew Hacking:
> >
> >
> > On Sat, Feb 14, 2015 at 5:55 PM, Dietrich Schulten <ds@escalon.de
> > <mailto:ds@escalon.de>> wrote:
> >
> >     Hi Andrew,
> >
> >     Am 13.02.2015 um 02:51 schrieb Andrew Hacking:
> >     >
> >     > What I mean by the above is that collections should not have any
related
> >     > resource content in them as their primary content.
> >
> >     See proposal below - would that cut it?
> >
> >
> > Probably not, see below.
>
> @Andrew:
> I am afraid you mistook the illustration of the current collection
> design for my proposal. I certainly mislead you by first giving a long
> example of the current design and only later making the proposal.

Ok sorry, my bad too.

>
> My proposal is:
>
> 1. Use hydra:Collection not as a container but as a descriptor, i.e.
> keep the actual items outside of the hydra:Collection object and make
> them direct values of the property they belong to. Drop hydra:member.

That is certainly aligned with what I was envisioning.

> @Andrew: the @context is restricted to define terms in the context, it
> is not a place to make arbitrary statements about things.
>

Thanks, its not clear how much you can or cannot say about a property.
would a page range or max/count for the offset and limit in the collection
descriptor be too much?

> 2. Use a hydra:IriTemplate on hydra:Collection at the *origin* object to
> inform the client about possible paging or ranged access. To support
> ranged access, introduce hydra:partial, hydra:offset and hydra:limit
> (see below for usage). Also use the Collection descriptor to inform the
> client about methods that can be performed on the collection, such as
> POSTing to it or searching inside it.
>

Excellent. Now this is starting to crystallize how I see collections.  Use
of a template aligns with other possible subsetting/filtering that could be
applied to the collection as well as supported operations on that
collection. E.g. a blog where you are able to filter comments on a post to
just those with a score of 3-5, or filtering and sorting a collection of
posts based on unread and createdAt, and then an operation for updating the
hasRead property.

My concern is the overhead/repetition of expressing the collection
descriptor for every instance of the property on every resource vs what can
be expressed once in @context.

> 3. Let the list of items be a plain list without surrounding container
> because such a container around the items causes problems in the RDF
> model. ("/alice foaf:knows hydra:Collection" makes RDF tools think that
> the hydra:Collection is a foaf:Person because foaf:knows defines that
> its values are foaf:Person)
> 4. The list of items can either be added as direct property values to
> the origin object (coming from HAL I call this embedding) or it can be
> kept outside, in which case the property value is a link. If that link
> is dereferenced, you get a plain list of items without surrounding
> container. See example responses below.
>

What would be a general approach to "including" related resources in a
payload without embedding under a property? A number of json apis support
inclusion of related resources and internal payload referencing to avoid
1+N queries and duplication of included resources. They typically put the
included resources in a reserved container within the payload. A use case
being: consider a response with100 people, where it is desirable to include
organisations to which they are a member of and many of those people being
members of the same organisations. It would be undesirable to fire off 100
queries to get all the organisations (1+N query problem), and with
embedding it would be undesirable to have duplicates.

> 5. In order to say things about the collection directly in the context
> of the collection response, we must use something else but the
> collection response body, because the body contains just items and there
> is nothing to attach additional properties to the collection.

Why can't references target a specific fragment in the response body? This
would allow other things to be present in the body, like
auxiliary/included  resources or collection meta data if desired.

> Proposal:
> use rfc-5988 Link headers for that. We can use the registered IANA rels
> 'next', 'prev' for paging. We can also use any Linked Data attribute to
> point to anything from the collection response because non-registered
> rels (aka extension rels) are URIs. We already use Link-Header for other
> purposes, so this is not an entirely new thing.
>

I don't have a problem with this, but I also don't have a problem with
saying absolutely nothing. The client asked the question so it knows the
context already via the collection descriptor it used. We don't provide all
back links to all possible/conceivable collections to which the response
could belong so I just see it as just one less set of back links.

> 6. We could use the Link-Template header [1] to inform the client about
> the offset/limit template inside the collection response. But
> Link-Template is a draft. (The Link header is not suitable for
> templates, because its href must be a URI, not a URITemplate.)
>

I find that a more desirable option than RFC 5988 next/prev links since the
template represents the full set of possibilities (random access, filtering
and sorting of collections, given paging implies some sort order for
stability). However the template would be scoped according to the origin
and given the origin specifies the full collection descriptor perhaps a
pointer to the collection descriptor at the origin could be considered
instead? In pure json land it would be a json pointer but if you want
something that is representation agnostic then probably just a uri.

> For examples, see below.
>
> [1] http://tools.ietf.org/html/draft-nottingham-link-template-01
>
> Example responses illustrating my proposal:
>
> >
> >     // server embeds a collection of people Alice knows
> >     {
> >       "@id": "/alice",
> >       "foaf:name": "Alice",
> >       "foaf:knows": [
> >         {"@id":"/bob", "foaf:name": "Robert Rumbaugh"},
> >         {"@id":"/zelda", "foaf:name": "Zelda Zackney"}
> >       ],
> >       "collection": [
> >         {
> >         "@id": "/alice/friends",
> >         "@type": "Collection",
> >         "manages": {
> >           "property": "foaf:knows",
> >           "subject": "/alice"
> >         },
> >         "search" : ... an iritemplate,
> >         "operation" : ... supportedOperations on /alice/friends
> >       ]
> >     }
> >
> >
> >     // server points to external resource with offset/limit
> >     {
> >       "@id" : "/alice"
> >       // plain link to friends:
> >       "foaf:knows" : { "@id": "/alice/friends" },
> >       // saying things about the management of /alice/friends:
> >       "collection": [
> >         {
> >         "@id": "/alice/friends",
> >         "@type": "Collection",
> >         "manages": {
> >           "property": "foaf:knows",
> >           "subject": "/alice"
> >         },
> >         "partial": {
> >             "@type": "IriTemplate",
> >             "template": /alice/friends{?offset,limit}
> >             "mapping": [
> >               {
> >               "@type": "IriTemplateMapping",
> >               "variable": "offset",
> >               "property": "hydra:offset"
> >               },
> >               {
> >               "@type": "IriTemplateMapping",
> >               "variable": "limit",
> >               "property": "hydra:limit",
> >               }
> >             ]
> >         }
> >       }
> >     }
> >
>
> >     The target resource returned from /alice/friends is a json-ld set of
> >     foaf:Person, not a hydra:Collection.
> >
>    The response has the following link header to point to the
>    next page.
>
>    Header:
>    Link: <http://example.com/alice/friends?page=2>; rel="next"
>    Body:
> >     [
> >       {"@id":"/bob",
> >        "@type": "http://xmlns.com/foaf/0.1/Person",
> >        "http://xmlns.com/foaf/0.1/name": "Robert Rumbaugh"
> >       },
> >       {"@id":"/zelda",
> >        "@type": "http://xmlns.com/foaf/0.1/Person",
> >        "http://xmlns.com/foaf/0.1/name": "Zelda Zackney"
> >       }
> >     ]
> >
>
> Best regards,
> Dietrich
>

Received on Monday, 16 February 2015 12:36:46 UTC