Filters as views (ISSUE-45)

Hi,

Our discussions around ISSUE-45 [1] (hydra:filter) got a quieter recently. I
used the time over Christmas to thinker with various designs and think I
made some quite good progress. The more I thought about the problem, the
clearer it became to me that the solution might be to look at it from a
different angle. What we want to describe are different views onto an
(abstract) resource - in our case a collection. This is similar to
representations in REST but not the same. Representations don't have
identifiers in the form of URLs - our views do. In other words, a view is a
derived resource, not a representation.

We have been discussing introducing a hydra:filter property that takes a
IriTemplate as value to reach such a filtered view. While this would
technically work, I don't think it would be the best solution. It doesn't
generalize nicely and is difficult to compose with other features. My
proposal is to generically describe to a client how it can get to alternate
views. All that is left to address ISSUE-45 is then to describe, what
variables in the URL template can be used as filters.

Here's a simple example illustrating how I imagine it to work. Let's assume
we have a collection /friends and want to filter it by the gender. This
could be described as follows:

  @id: /friends
  member: [ ... ]
  view: {
    @type: ViewTemplate, IriTemplate
    template: /friends{?gender}
    mapping: {
      variable: gender
      property: http://schema.org/gender
      filter: true
  }

This is easily expandable. We can either allow more complex values for
hydra:filter or introduce additional properties. It is also generalizable to
other contexts (such as having a parameter that acts as a filter in an
operation) and use cases. One such use case might be to only return some
fields of a resource:

  @id: /person/markus
  ...
  view: {
    @type: ViewTemplate, IriTemplate
    template: /friends{?fields}
    mapping: {
      variable: fields
      fieldSelector: true
      anyOf: [ name, birthdate, address, ... ]
  }

[I'm not sure yet whether the example above should include a property in the
mapping or not; the value of anyOf is just to illustrate the concept, it
would probably be need to be a bit more descriptive]

You might wonder what the result of a GET on the ViewTemplate is. My current
thinking is that, in the case of a collection, it should be a
PartialCollectionView. I don't think we need a pointer back to the
"original" collection, having the ViewTemplate on the filtered collection
should be enough. If the users doesn't include any filters and the server
doesn't decide to paginate, it would simply return the full collection.

So, to summarize it, my proposal to address ISSUE-45 is to introduce three
new concepts:
  - hydra:view, a property that can take a
  - hydra:ViewTemplate (subclass of IriTemplate) as value (and in the future
perhaps also links to alternate views directly) and
  - hydra:filter, a property to designate parameters/variables that act as
filters. For the time being it's range is a boolean (schema:rangeIncludes to
keep the door open for extensions in the future)

What do you think? Is this too abstract? Did I miss anything? Or does it
look good to you? :-)


Cheers,
Markus


[1] https://github.com/HydraCG/Specifications/issues/45



--
Markus Lanthaler
@markuslanthaler

Received on Sunday, 10 January 2016 17:14:17 UTC