RE: Local identifiers in IriTemplates

Hi Dietrich,

On 13 Dez 2014 at 11:06, Dietrich Schulten wrote:
> Preparing the release of hydra-java with support for templates, I
> wanted to ask for your opinions.

Awesome!


> I understand templates as an equivalent to a GET http form, especially
> since they have no facility to build a request body.

Yeah, they are similar to GET requests. If you define a property to be a
hydra:TemplatedLink you can also associate operations (via
hydra:supportedOperation) to it and specify what data is expected in the
body as usual. Currently there's no way to achieve that inline.. but it
might actually be a good idea to also allow supportedOperation directly on a
IriTemplate.


> In Spring-Hateoas there is a Resources class which holds a collection
> of items and allows to add links outside the item collection which
> apply to the entire collection. This would be the typical place to
> define a search template.
> 
> Currently hydra-java renders them like this, assuming that the user
> has added the search template using a rel hydra:search:
> 
> {
>     "@context":
>     {
>         "@vocab": "http://schema.org/",
>         "hydra": "http://www.w3.org/ns/hydra/core#"
>     },
>     "@type": "hydra:Collection",
>     "hydra:search": {
>         "@type": "hydra:IriTemplate",
>         "hydra:template": "http://localhost/events{?eventName}",
>         "hydra:mapping": [
>         {
>             "@type": "hydra:IriTemplateMapping",
>             "hydra:variable": "eventName",
>             "hydra:required": true,
>             "hydra:property": "http://schema.org/name"
>         }]
>     },
>     "hydra:member": [
>         {
>           "@type": "Event",
>           "@id": "http://localhost/events/1",
>           "name": "Gang of Rhythm Tour"
>           ...
>         },
>         { ... another event }
>     ]
> }
> 
> Is this correct RDF-wise? I am pretty sure it is, since I think I am
> not adding any new properties to the hydra:Collection or other classes
> which haven't been there in the first place.

Yeah, LGTM.


> But what if I wanted to add another template which does not fit so
> nicely with schema.org?
> 
> Let's say I want to search by some database identifier in addition to
> the search by name, so I make hydra:search an array and add another
> IriTemplate:
> 
> "hydra:search":
>  [
>         {
>             "@type": "hydra:IriTemplate",
>             "hydra:template": "http://example.com/events/{eventId}",
>             "hydra:mapping": [
>             {
>                 "@type": "hydra:IriTemplateMapping",
>                 "hydra:variable": "eventId",
>                 "hydra:required": true,
>                 "hydra:property": "eventId" <-- what to put here?

You would need to define a property for this and assign it the intended
meaning, i.e., document what it is.

>             }]
>         },
>         {
>             "@type": "hydra:IriTemplate",
>             "hydra:template": "http://example.com/events{?eventName}",
>             ... see above
>         }
> ]

I actually haven't thought about having multiple IRI templates with
hydra:search.
 
> It seems quite common to make an internal identifier such as a
> database ID part of a resource URI, and it is not far fetched to allow
> a client to look up an item by that id.

Yep.. I just wonder whether hydra:search is the best property for this...
but it's certainly not wrong. Quite a while ago we discussed having
something like hydra:memberTemplate for use cases like this. See [1] and
[2].


> For instance, think of an event location which maintains dozens of
> events wants to review the event data of a particular event in the api
> of an event platform.
> Or, I have a case in mind where there are millions of customers so not
> even a paged collection makes much sense for an API which allows
> access to customer data. You really want to be able to say "get me
> this particular customer by her customer id".
> But what should I use as value of hydra:property in such a situation?

Since this is probably something which only exists in your system (unlike an
ISBN or EAN code for instance) you would need to create your own property.


> I could of course come up with a mini-vocabulary which describes that
> id for my API. The reason I want to avoid that is the difficulty to
> write a generic client which can handle this type of situation, if it
> has to depend on vendor-specific vocabs.

Well, the thing is that such an ID doesn't mean much outside of your system.
It is an implementation detail. In fact, if your "clients" (whether that
means humans or machines doesn't matter in this case) would remember aka
bookmark the URL instead of the ID the problem would actually solve itself.


> Could we have a property like hydra:localIdentifier and describe it as
> "an attribute which identifies a thing in its local context"? One

Honestly, I don't think that would make a lot of sense. That identifier has
no value at all without the context.


> could use a hydra:label to give a hint to humans which interact with
> the system.

Sure, but why can't you do the same with your own mini-vocabulary?


> Like this:
> 
> "@type": "hydra:IriTemplateMapping",
> "hydra:variable": "eventId",
> "hydra:required": true,
> "hydra:property": "hydra:localIdentifier",
> "hydra:label": "Enter your event number"

Hydra is primarily for machines. If you need to fall back to the label, then
you don't need to map the variable to a property. A human is smart enough to
fill in the right data by reading the label, a machine unfortunately isn't.
Without the context it also wouldn't know what localIdentifier to use in
this specific case (event ID, location ID, user ID...?) making it
essentially useless information.


> "@type": "hydra:IriTemplateMapping",
> "hydra:variable": "loginId",
> "hydra:required": true,
> "hydra:property": "hydra:localIdentifier",
> "hydra:label": "Enter your user name or email address"
> 
> A machine client could be programmed to start with some knowledge
> about the context, for instance that it should use 4711 as a known
> hydra:localIdentifier when navigating the API.

Only if you code a special client for that specific API... and even in that
case it would be tricky as you might have multiple IRI templates which take
different localIdentifiers.


> Such a machine client
> could be a client framework used by a mobile app, which operates in
> the context of an authenticated user and can tell the client framework
> about it. If we could also use hydra:returns on a template, it would
> also be clear exactly what the localIdentifier identifies. That way I
> could tell the machine client that it knows localIdentifiers both of
> an Event and a Person which it should use when performing a ReviewAction.

And if you would use the URL instead of the ID in the mobile app you
wouldn't have all of those issues altogether :-)


> Or is there a vocabulary out there which already has such a property?

No :-)


Cheers,
Markus


[1] http://www.w3.org/mid/030901cee794$2bcfae50$836f0af0$@lanthaler@gmx.net
[2] https://github.com/HydraCG/Specifications/issues/16



--
Markus Lanthaler
@markuslanthaler

Received on Sunday, 14 December 2014 19:45:34 UTC