Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend PartialCollectionView with template variables' values #148

Open
tpluscode opened this issue Nov 4, 2017 · 16 comments
Open

Extend PartialCollectionView with template variables' values #148

tpluscode opened this issue Nov 4, 2017 · 16 comments

Comments

@tpluscode
Copy link
Contributor

tpluscode commented Nov 4, 2017

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" }
  ] 
}
@tpluscode tpluscode changed the title Extend PartialCollectionView with currently set filter Extend PartialCollectionView with template variables' values Nov 4, 2017
@alien-mcl
Copy link
Member

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
Copy link
Contributor Author

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
Copy link
Member

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
Copy link
Member

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

@elf-pavlik
Copy link
Member

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
Copy link
Member

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
Copy link
Member

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

@tpluscode
Copy link
Contributor Author

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
Copy link
Member

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
Copy link
Contributor Author

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
Copy link
Contributor Author

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
Copy link
Member

asbjornu commented Dec 7, 2020

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
Copy link
Member

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
Copy link
Contributor Author

tpluscode commented Dec 8, 2020

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
Copy link
Member

asbjornu commented Dec 8, 2020

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
Copy link
Member

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:

  • that IRI template case
  • collection metadata like sorting
  • general resource projection (i.e. subset of predicates, etc.)

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants