HydraCG / Specifications

Specifications created by the Hydra W3C Community Group
Other
138 stars 26 forks source link

Linking to multiple PartialCollectionView from Collection #112

Closed literarymachine closed 7 years ago

literarymachine commented 7 years ago

When implementing pagination in a front end e.g. with Bootstrap, one often needs not only first / last / next / previous links but also an explicit list of pages. Neither in #42 nor in http://www.hydra-cg.com/spec/latest/core/#collections I can see this issue addressed; is there a suggested way of handling this in Hydra? Would it perhaps be an option to simply add an ordered list of PartialCollectionView to Collection using view?

{
  "@context": "http://www.w3.org/ns/hydra/context.jsonld",
  "@id": "http://api.example.com/an-issue/comments",
  "@type": "Collection",
  "totalItems": "4980",
  "member": [
    ... a subset of the members of the Collection ...
  ],
  "view": {
    "@list": [
      {
        "@id": "http://api.example.com/an-issue/comments?page=1",
        "@type": "PartialCollectionView"
      },
      {
        "@id": "http://api.example.com/an-issue/comments?page=2",
        "@type": "PartialCollectionView"
      },
      {
        "@id": "http://api.example.com/an-issue/comments?page=3",
        "@type": "PartialCollectionView"
      }
    ]
  }
}

It also seems that in such a use case, it would be ok for first / last / next / previous to be omitted.

lanthaler commented 7 years ago

A list may be an option but would likely break clients that don't expect it. What would definitely work though is to express it explicitly as a linked list. Something like

  "view": [
    {
      "@id": "http://api.example.com/an-issue/comments?page=1",
      "@type": "PartialCollectionView",
      "first": "/an-issue/comments?page=1",
      "next": "/an-issue/comments?page=2",
      "last": "/an-issue/comments?page=4"
    },
    {
      "@id": "http://api.example.com/an-issue/comments?page=2",
      "@type": "PartialCollectionView",
      "previous": "/an-issue/comments?page=1",
      "next": "/an-issue/comments?page=3",
    },
    {
      "@id": "http://api.example.com/an-issue/comments?page=3",
      "@type": "PartialCollectionView",
      "previous": "/an-issue/comments?page=2",
      "next": "/an-issue/comments?page=4",
    },
    {
      "@id": "http://api.example.com/an-issue/comments?page=4",
      "@type": "PartialCollectionView",
      "previous": "/an-issue/comments?page=3"
    }
  ]

Whether you include first/last in all views or just one shouldn't matter too much.

An alternative we discussed on the mailing list if I remember correctly would be to describe these relationships with an IriTemplate.

tpluscode commented 7 years ago

I second Markus on discouraging @list. It may make sense to keep the structure as an ordered list but the underlying RDF model is awkward at best.

My question is, how are you intending to consume it? As JSON or RDF? If you expect a nice JSON structure, which wouldn't affect the RDF I could suggest `"@container": "@index".

{
  "@context": [ 
    "http://www.w3.org/ns/hydra/context.jsonld",
    { 
      "view": { "@id": "hydra:view", "@container": "@index" }
    }
  ],
  "view": {
      "1": {
        "@id": "http://api.example.com/an-issue/comments?page=1",
        "@type": "PartialCollectionView"
      },
      "2": {
        "@id": "http://api.example.com/an-issue/comments?page=2",
        "@type": "PartialCollectionView"
      },
      "3": {
        "@id": "http://api.example.com/an-issue/comments?page=3",
        "@type": "PartialCollectionView"
      }
  }
}

This way you don't change the RDF representation but give your client simpler navigation of the JSON structure.

RubenVerborgh commented 7 years ago

Why not an IRI template / hypermedia control with page number as a parameter?

For this reason, paging has a dependency on IRI templates in the suggested new architecture diagram.

literarymachine commented 7 years ago

Why not an IRI template / hypermedia control with page number as a parameter?

I am unsure how these would look. In my case for example, I don't have explicit page parameters but from and size. The client could probably calculate these based on totalItems, but doesn't the server knows best which pages the collection consists of?

literarymachine commented 7 years ago

A list may be an option but would likely break clients that don't expect it.

Right.

What would definitely work though is to express it explicitly as a linked list.

I'll go with either this or the @index solution in https://github.com/HydraCG/Specifications/issues/112#issuecomment-290213681. Thanks!

lanthaler commented 7 years ago

I'll go with either this or the @index solution in #112 (comment).

Please keep in mind that the @index solution only works for clients that interpret that specific JSON structure which is quite brittle unless you control both the server and all the clients. The JSON-LD document isn't actually expressing which view is which page.