RE: Filters as views (ISSUE-45)

On 12 Jan 2016 at 13:56, Ruben Verborgh wrote:
>> What's the difference between a PartialCollectionView and a Collection?
IMO,
>> it's the same difference as the one between a filtered collection and the
>> collection itself.
> 
> Could you (help) provide definitions for both of them?
> My hunch is that such definitions will be troublesome,
> showing that the difference is not black and white.
> (I have trouble coming up with definitions myself.)

I think the definitions we currently have in the spec are mostly fine
(emphasis mine):

  A collection holding references to a number of related resources.

  A PartialCollectionView describes a partial view of a Collection. Multiple
  PartialCollectionViews **can** be connected with the the next/previous
  properties to allow a client to retrieve all members of the collection.


>>> What is a view and what is a collection?
>>> How can we see/know if a resource is one of the other?
>> 
>> Just as in paging. The server tells the client.
> 
> I meant more:
> how does a server developer know the difference?

Maybe it helps to make this a bit more concrete. Let's assume we have a
collection holding information about you and me.
With a page size of 1, a GET /collection?page=2 would yield

  {
    "@id": /collection",
    "@type": "Collection",
    "totalItems": 2,
    "member": [
      { "@id": "/ruben", "name": "Ruben" }
    ],
    "view": {
      "@id": /collection?page=2",
      "@type": "PartialCollectionView",
      "first": "/collection?page=1",
      "previous": "/collection?page=1",
      "last": "/collection?page=2"
    }
  }

Now let's describe to the client how it can filter that collection (can be
integrated in the previous response but to keep the example succinct I
simplified it:

  {
    "@id": /collection",
    "@type": "Collection",
    "view": {
      "@type": "ViewTemplate",
      "template": "/collection{?n}",
      "mapping": {
        "variable": "n"
        "property": "name"
        "filter": true
      }
    }
  }

This would tell a client, that it can filter the members of /collection by
the property "name" (could be mapped to schema.org/name for instance).
The GET /collection?n=Markus would then yield this result:

  {
    "@id": /collection",
    "@type": "Collection",
    "totalItems": 2,
    "member": [
      { "@id": "/markus", "name": "Markus" }
    ],
    "view": {
      "@id": /collection?n=Markus",
      "@type": "PartialCollectionView",
      "totalItems": 1
    }
  }

I added totalItems to the PartialCollectionView as we discussed previously.
Now let's assume the collection is much bigger and the server decides to
paginate the filtered result. The response would then look as follows (I
omit the template for clarity, but just as before, it could obviously be
included):

  {
    "@id": /collection",
    "@type": "Collection",
    "totalItems": 2489,
    "member": [
      { "@id": "/markus", "name": "Markus" },
      ... other members that match the filter ...
    ],
    "view": {
      "@id": "/collection?n=Markus",
      "@type": "PartialCollectionView",
      "totalItems": 58
      "first": "/collection?n=Markus",
      "next": "/collection?n=Markus&page=2",
      "last": "/collection?n=Markus?page=6"
    }
  }

IMO this illustrates quite nicely how composable this approach is. And apart
from keeping the top-level's object @id set to /collection (which we decided
to do in the pagination design discussion and might be a bit
counterintuitive to some people at first) I think it is also quite
straightforward.


If you don't like this approach, could you please point out in the examples
what exactly you don't like. Could you, in that case, please also rewrite
the examples to illustrate how you would see this working with the alternate
proposal.


Cheers,
Markus


--
Markus Lanthaler
@markuslanthaler

Received on Tuesday, 12 January 2016 20:44:06 UTC