- From: Gregg Kellogg <gregg@greggkellogg.net>
- Date: Tue, 4 Feb 2014 10:56:29 -0800
- To: Markus Lanthaler <markus.lanthaler@gmx.net>
- Cc: public-hydra@w3.org
On Feb 4, 2014, at 10:26 AM, Markus Lanthaler <markus.lanthaler@gmx.net> wrote: > Hi Gregg, > > On Monday, February 03, 2014 11:24 PM, Gregg Kellogg wrote: >> >> Excuse me for some random thoughts, but I've been reconciling using >> Hydra for an API which typically returns JSON-LD representations of >> entities described using schema.org. Similar issues may exist with the >> schema.org action vocabulary as well. As a simple example, I may want >> to express follows information for a Person. In Turtle, this might look >> like the following: >> >> <http://example/people/gregg> a schema:Person; >> schema:name "Gregg Kellogg"@en; >> schema:follows <http://example/people/markus>, >> <http://example/people/kingsley> ... >> >> However, given that the list of potentially people I follow could be >> large; using Hydra I may construct this using a separate relationship >> to a Collection: >> >> <http://example/people/gregg> a schema:Person, :ApiPerson; >> :follows <http://example/people/gregg/follows> . > > This is a general problem of RDF. AFAICT, there's no way general way to > solve this issue for sets. If you would use a list, you could at least use > the list's head node (which generally is a blank node). Remember our > discussions in the JSON-LD group? > > Both Schema.org with its ItemList and Hydra with its Collection take a > rather pragmatic approach. We could of course go ahead and define a > Collection's semantics so that > > x p c . > c hydra:members y . > > would entail > > x p y . > > which is what you are looking for, right? That would be a way to do it with semantics, but I don't think this is as useful for the target audience. Also, I presumed that hydra:members would be an ordered collection (e.g., @container: @list), but that might not necessarily be the case; my examples had the values of hydra:members in a list, but this would be incompatible with such an entailment rule (sadly). >> :ApiPerson a hydra:Class; >> hydra:supportedProperties [hydra:property schema:name], >> [hydra:property :follows] . >> >> :follows a hydra:Link >> rdfs:label "follows"; >> rdfs:comment "Collection of followed people"; >> rdfs:domain schema:Person; >> rdfs:range schema:Person; > > This range isn't correct unless you want > <http://example/people/gregg/follows> to be of type schema:Person. Yes, it should be hydra:Collection. I supposed it could also be a sub-class of hydra:Collection where the range of hydra:member could be restricted to be schema:Person. >> hydra:supportedOperations [ >> hydra:method "GET"; >> hydra:returns hydra:Collection >> ] . >> >> If the referenced collection contained the following data: >> >> <http://example/people/gregg/follows> a hydra:Collection; >> hydra:members (<http://example/people/markus> >> <http://example/kingsley> . >> >> After loading both the original document and the collection into a >> graph, I would now have the following: >> >> <http://example/people/gregg> a schema:Person, :ApiPerson; >> :follows <http://example/people/gregg/follows> . >> <http://example/people/gregg/follows> a hydra:Collection; >> hydra:members (<http://example/people/markus> >> <http://example/kingsley> . >> >> This now does not describe what I would want using the schema.org >> definitions. One way to reconstruct what I want would be to add more >> data to the collection document: >> >> <http://example/people/gregg/follows> a hydra:Collection; >> hydra:members (<http://example/people/markus> >> <http://example/kingsley> . >> <http://example/people/gregg> schema:follows >> <http://example/people/markus>, <http://example/people/kingsley> . >> >> This is actually easier to do in JSON-LD: >> >> { >> "@context": { >> "hydra": "http://www.w3.org/ns/hydra/core#", >> "schema": "http://schema.org/", >> "follower": {"@reverse": "schema:follows"} >> } >> "@id": "http://example/people/gregg/follows", >> "@type": "hydra:Collection", >> "members": [ >> { "@id": "http://example/people/markus", "follower": >> "http://example/people/gregg"}, >> { "@id": "http://example/people/kingsley", "follower": >> "http://example/people/gregg"} >> ] >> } > > That's the most straightforward solution I can think of. > > >> The issue is better for single-valued properties, as the property value >> would be the same as the entity identifier, which would result in what >> you would expect when merging both entity definitions. >> >> I guess the question is, is this an expected usage pattern? Should the >> collection examples represent this, or should it be described as a >> recommended practice? Perhaps I've missed something. > > I think this is definitely one of the most common usage patterns in Web > APIs. The question whether there needs to be a direct link between the > resources or whether you can go "through" a Collection is another question. > As long as the consumer of the data understands Collection/ItemList I think > it's not a problem. If it doesn't, it is of course. From an SEO perspective, it's not clear that schema.org partners would make this connection, even though a ItemList has been defined. For that to be the case, I would expect that they would allow any property to take an ItemList in addition to the specified property range and do the inference you suggested above. > Maybe Ruben has something more to say about this.. N3 *might* allow a nicer > solution but I think that's out of scope. Isn't it? Yes, N3 also have inverse links, and it's been proposed for a Turtle follow-on, in order to better align with SPARQL. In this case, I don't think it really helps that much. (N3 also has "is x of" for inverse property relationships, e.g. "Gregg Kellogg" is foaf:name of <gregg> .) In any case, this isn't too helpful for describing this use case and N3 isn't a standard. Thanks for the response, at least I know that my understanding of the issues doesn't seem to be that far off. Gregg > -- > Markus Lanthaler > @markuslanthaler > >
Received on Tuesday, 4 February 2014 18:56:58 UTC