HydraCG / Specifications

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

Extend PartialCollectionView with template variables' values #148

Open tpluscode opened 6 years ago

tpluscode commented 6 years ago

We have a way for defining collection filtering using template but when the partial representation comes back from the server it doesn't include the variables used on said template. To illustrate, here's a collection snippet from the wiki:

{
  "@id": "/markus/friends",
  "@type": "Collection",
  "totalItems": 578,
  "member": [  ],
  "view": [
    {
      "@id": "/markus/friends?first=Ruben",
      "@type": "PartialCollectionView",
      "totalItems": 15
    },
    {
      "@type": "ViewTemplate",
      "template": "/markus/friends{?first,last}",
      "mapping": [
        { "variable": "first", "property": "schema:givenName" },
        { "variable": "last", "property": "schema:familyName" }
      ]
    }
  ]
}

Currently we have no explicit way to determine that the template was constructed with values { "first": "Ruben" }. Of course it is technically possible to reverse the IRI template expansion, some libraries do support that, but what if there are more than one ViewTemplate?

Why do I think it's important? Because without this importation the client has a a hard time to fill a filtering form in the UI.

What I'd see here is an optionally array of variables under the PartialCollectionView. Something like

{
  "@id": "/markus/friends?first=Ruben",
  "@type": "PartialCollectionView",
  "totalItems": 15,
  "templateVariables": [
    { "variable": "first", "value": "Ruben" }
  ] 
}
alien-mcl commented 6 years ago

Why do you expect server to provide the state the client produced? If the client initiated that filtering, it is it's stake to keep track of filters used.

tpluscode commented 6 years ago

If the client initiated that filtering, it is it's stake to keep track of filters used.

I knew that question would come 😁.

Because bookmarks. The client may not have that information if it starts directly from a bookmarked resource URI.

alien-mcl commented 6 years ago

Hold your horses. I believe a bookmark would refer to some kind of client state (i.e. http://my.web.application/some-route/some-view?with-parameters) that would invoke some call on the server with filters. If so, client should already keep track of that call. If it's not the case - change your client :). I think it's like asking SQL server to provide it's WHERE clause decomposed. I know it would be a nice-to-have, but still I believe it's not the stake of the server.

lanthaler commented 6 years ago

There would be the option to leverage hydra:manages for this. It is able to express at least direct equality filters.

elf-pavlik commented 6 years ago

There would be the option to leverage hydra:manages for this. It is able to express at least direct equality filters.

Do you mean that an instance of Collection would have its manages block and an instance of PartialCollectionView (on that collection) would have its own distinct manages block?

Actually this in a way fits seeing Collection as PartialView on the whole Dataset - related to #142 I'll add a comment there to keep this issue here focused on @tpluscode initial inquiry.

lanthaler commented 6 years ago

Do you mean that an instance of Collection would have its manages block and an instance of PartialCollectionView (on that collection) would have its own distinct manages block?

Yes, a PartialCollectionView could have it's own manages block

alien-mcl commented 3 years ago

@tpluscode does the answer satisfies you and can this issue be closed?

tpluscode commented 3 years ago

No, it is not the same. The template does not have to directly correspond the collection members.

For example a query like people?minAge=18 does not necessarily translate to a "member assertion". As Markus himself noticed, only exact equality can be currently expressed this way. Also, I think it's a separate concern

alien-mcl commented 3 years ago

Server may provide a manages (or after recent changes memberAssertion) block saying each member is an instance of a class expressed via OWL restriction with allValuesFrom and DataComparison like in this example. Not pretty, but doable.

As I wrote earlier - I'm against throwing this kind of concepts into the hydra (it's up to the client to maintain it's state), but I want to be sure hydra provides concepts for extensions.

tpluscode commented 3 years ago

I don't mind this being an extension to Hydra Core.

Although all it takes is a single property which would provide the exact values needed to reconstruct the template. Nothing substantial

tpluscode commented 3 years ago

it's up to the client to maintain it's state

And I said that before, it is not about client maintaining its state. If you a client starts by dereferencing a collection with filters, they have no way for figuring out how to construct that same template

asbjornu commented 3 years ago

Since Hydra has a way to define URI templates, I find it strange to not use Hydra's existing vocabulary to express how the currently requested URI was constructed and can be manipulated by the client. I see no reason why this should be delegated to an extension and not reside in Hydra Core.

alien-mcl commented 3 years ago

I'm not sure which existing vocabulary terms are you referring to @asbjornu, but let's try to bent our minds and mint some example:

{
  "@id": "/markus/friends",
  "@type": "Collection",
  "totalItems": 578,
  "member": [...],
  "view": [
    {
      "@id": "/markus/friends?first=Ruben",
      "@type": "PartialCollectionView",
      "totalItems": 15,
      "template": "/markus/friends{?first}",
      "mapping": [{
        "variable": "first",
        "object": "Ruben"
      }]
    }
  ]
}

I did not make any analysis on possible range/domain violations in the example above. I aimed not to introduce any new terms. While I'm not convinced it is a server's concern to describe what client had in mind, let's imagine we can have a cheap yet working solution. Any ideas? @asbjornu - do you have any specific approach we could take into account?

tpluscode commented 3 years ago

Ok, above I said that only a single property is required, because the actual template variables can also be expressed as RDF. That is how the mapping works, which I only realised quite recently

Given a template as above

{
  "@type": "IriTemplate",
  "template": "/markus/friends{?first}",
  "mapping": [{
    "variable": "first",
    "property": "schema:givenName"
  }]
}

To construct the URI /markus/friends?first=Ruben I would use a blank resource using the mapped property:

{
  "schema:giveName": "Ruben"
}

Thus, all I need is really just a property to attach this to the constructed view (or collection, or somewhere, I'm no 100% sure TBH). Now that I think about this, might actually add a second property to point to the actual IriTemplate in case there were multiple.

Here' a complete representation, diffed from the initial snippet

{
  "@id": "/markus/friends",
  "@type": "Collection",
  "totalItems": 578,
  "member": [  ],
  "search": {
+   "@id": "_:template",
    "template": "/markus/friends{?first,last}",
    "mapping": [
      { "variable": "first", "property": "schema:givenName" },
      { "variable": "last", "property": "schema:familyName" }
    ]
  },
  "view": [
    {
      "@id": "/markus/friends?first=Ruben",
      "@type": "PartialCollectionView",
      "totalItems": 15,
+     "fromTemplate": "_:template",
+     "templateVariables": {
+       "schema:giveName": "Ruben"
+     }
    }
  ]
}

See what happened:

  1. The view references the template used to construct the URI
  2. The templateVariables is a simple RDF resource with properties which map to resource variables
asbjornu commented 3 years ago

I'm not sure which existing vocabulary terms are you referring to @asbjornu

What I meant was that we already have the IriTemplate type. It feels strange to have a type with associated properties that should be fully capable of expressing what we're after here, but choosing not to do it because we deem it outside the scope of Hydra to do so.

That being said, I'm not fluent enough in RDF to actually propose a solution.

alien-mcl commented 3 years ago

While I think that it is not a subject for the core, I'd love to have some gate opened for extensions here. I see several situations that could benefit from that gate:

Maybe a general property, i.e. hydra:metaData that could be a super property of other extensions is a good direction? There is also an option for profiles mentioned in #221. Feel free to deliberate more!