HydraCG / Specifications

Specifications created by the Hydra W3C Community Group
Other
139 stars 25 forks source link

Introduce something like hydra:memberTemplate #16

Closed lanthaler closed 3 years ago

lanthaler commented 10 years ago

This was proposed by @rubenverborgh on the mailing list:

Well, same thing in principle

:membersHaveTemplate a hydra:TemplatedLink .

Of course Hydra can't know what :membersHaveTemplate really means

Well, that's exactly what I propose. This precise link is going to be so common that I think we want it in Hydra itself. Perhaps memberTemplate is a better name. (Note: I'm unsure on how to use the hydra:members predicate, I might be doing it wrong.)

Example of what I'd like:

</users> hydra:members </users/alfred>.
</users> hydra:members </users/bernard>.
</users> hydra:members </users/corey>.
</users> hydra:membersTemplate [
                        a hydra:IriTemplate;
                        hydra:template "/users/{userid}"
].

The semantics of the hydra:membersTemplate property would be: "members can be dereferenced by using the following template".

(Not: "members need to have this template".)

Would such a property fit in the Hydra core vocabulary?

lanthaler commented 10 years ago

PROPOSAL: Do not introduce hydra:memberTemplate but explain how hydra:filter (a specialization of hydra:search, see ISSUE #45) can be used instead.

tpluscode commented 6 years ago

I now realise that the initial semantics of this property was different.

Maybe we should close this one and create a new issue to update the spec?

lanthaler commented 6 years ago

I think we can simply revisit the decision given the new use cases.

tpluscode commented 6 years ago

Sure.

To recap, #143 reintroduces hydra:memberTemplate as a way to specify a way to create new members of a collection:

{
    "@id": "/api/events",
    "@type": "hydra:Collection",
    "hydra:memberTemplate": {
        "@type": "IriTemplate",
        "hydra:template": "http://example.com/api/event{/slug*}",
        "hydra:variableRepresentation": "hydra:BasicRepresentation",
        "hydra:mapping": [ ... ],
        "hydra:operation": [
          {
            "@type": [ "hydra:Operation", "schema:CreateAction" ],
            "method": "PUT"
          }
        ]
    }
}

That said I don't think the original proposal is at odds with that. If hydra:memberTemplate was defined as a templated link, that would explicitly allow the client to attempt GET.

lanthaler commented 6 years ago

Agreed. I’ll send a mail to the list to announce this.

lanthaler commented 6 years ago

PROPOSAL: Introduce hydra:memberTemplate that describers the URL structure of members of a collection. It enables clients to directly access members of a collection given it has the necessary information to resolve the IRI template and to create new members with partially client-controlled URLs.

alien-mcl commented 6 years ago

I'm still wondering whether separate predicate is really necessary. Indeed it will shorten the syntax and enforce some extra logic, but would it make the existing IriTemplate obsolete/forbiden for collections?

</api/events> a hydra:Collection;
    hydra:memberTemplate [
        hydra:template "/api/events/{id}";
        hydra:variable "id";
        hydra:property some:property
    ] .

alternatively:

</api/events> a hydra:Collection;
    api:member [
        a hydra:IriTemplate;
        hydra:template "/api/events/{id}";
        hydra:variable "id";
        hydra:property some:property 
    ] .
api:member a hydra:Link .
lanthaler commented 6 years ago

would it make the existing IriTemplate obsolete/forbiden for collections?

No, it wouldn't. It would just standardize a common need so that people don't have to resort to custom concepts like api:member which a generic client wouldn't understand.

elf-pavlik commented 6 years ago

I'm still wondering whether separate predicate is really necessary. Indeed it will shorten the syntax and enforce some extra logic, but would it make the existing IriTemplate obsolete/forbiden for collections?

As I understand in definition of hydra:memberTemplate we could include

hydra:memberTemplate rdfs:range hydra:IrITemplate .

similar to http://www.hydra-cg.com/spec/latest/core/#hydra:search Please also notice in http://www.hydra-cg.com/spec/latest/core/#the-hydra-core-vocabulary-in-json-ld

hydra:search a hydra:TemplatedLink .

So based on your snippet we still get

</api/events> a hydra:Collection;
    hydra:memberTemplate [
        a hydra:IriTemplate ;
        hydra:template "/api/events/{id}";
        hydra:variable "id";
        hydra:property some:property
    ] .
hydra:memberTempate a hydra:TemplatedLink .

With defining it in hydra namespece, we improve interoperability. Clients like Herakles.ts would not understand meaning of api:member, Herakles.ts could just undertand the api:member a hydra:Link . but other then that it woudn't tell difference in meaning between api:member and foo:bar

Also hydra:TemplatedLink seems more accurate for hydra:memberTemplate than hydra:Link which you suggested for api:member. With all this in mind looking at what you propose

</api/events> a hydra:Collection;
-   hydra:memberTemplate [
+   api:member [
        a hydra:IriTemplate;
        hydra:template "/api/events/{id}";
        hydra:variable "id";
        hydra:property some:property 
    ] .
-hydra:memberTempate a hydra:TemplatedLink .
+api:member a hydra:Link .

I don't see it as improvement but contrary.

alien-mcl commented 6 years ago

As for the api:member - it's irrelevant from the client point of view. We just require a link between a collection and member's template, it can also be qwe:123. It doesn't need to be a hydra:Link as it will sit as a predicate, thus client could lookup IriTemplates hooked with any relation to the collection. Only drawback would be the fact that there would be no direct statement that the IriTemplate is actually for members. It's also not clear on how the client should behave when both constructs are encountered. @lanthaler already stated that the memberTemplate shouldn;t forbid the generic IriTemplate approach, thus it means that the client have to implement both, which is possibly unnecessary complication. Anyway - I just would think it over before adding new items to the spec.

elf-pavlik commented 6 years ago

It's also not clear on how the client should behave when both constructs are encountered. @lanthaler already stated that the memberTemplate shouldn;t forbid the generic IriTemplate approach, thus it means that the client have to implement both, which is possibly unnecessary complication.

I don't understand what do you mean by generic IriTemplate approach.

alien-mcl commented 6 years ago

The one that doesn't use this hypothetical memberTemplate, but api:member (or any other) instead.

elf-pavlik commented 6 years ago

So the only difference seems that with hydra:memberTemplate we have an instance of hydra:TemplatedLink (just like hydra:search) with clearly defined meaning, while with something like bespoke api:member clients which don't implement that additional api: vocab (eg. plain Heracles.ts) would just understand that they have an instance of hydra:TemplatedLink but not know anything about its meaning, rendering it something similar to rdfs:seeAlso.

At the same time, I agree that client pseudo code introduced in #143 seems to start with assumption that it has to look for hydra:TemplatedLink so that code would fail if service choses to add members by having operation - schema:CreateAction with POST directly on the collection. As we discussed during the call, we should not assume that we already found a solution to the challenge. I see it more as stil exploring certain possibility which we may still find not an appropriate approach.

alien-mcl commented 3 years ago

We've never reached a consensus with this feature. It was introduced into Heracles.ts some time ago but it was removed. I believe this is obsolete and hydra:memberTemplate is unnecessary, especially when it would probably involve GET operations on members rather than allow the client to work with PUTs and DELETEs. I think the generic approach works fine here.