Hi Ruben, Nice approach.
At the risk of getting too deep into the semantics and philosophy, might one expect that the members of the collection would be the subject of the statements in the collection resource rather than in object position? I guess another way to look at it is are the people the members of the collection or are the "X foaf:knows Y" statements the members. Not sure if it really matters or not. I've been working on a project recently where we used Puelia (implementation of Linked Data API) to serve up some linked data and ran into a few challenges with making these kind of lists discoverable. Can be broken down to a couple of use cases: 1. List of entities with a restriction on one or more properties e.g. list of people, list of red things 2. List of entities with a restriction on one or more inverse properties e.g. list of things that know me Basically boils down to outbound and inbound links. Your example covers number one, and guess you can easily do something like this for the second: [ hydra:memberOf </people/markus/friends> ] foaf:knows </people/markus> . Actually we currently implemented this with multiple views of a resource and using the "inverse property" feature of Puelia, but this does not support pagination. So in some cases one of these views can return a huge list. To put that into the context of the Markus example, we currently do something like: /people/markus?_view=friends Which could return a list of thousands of things where pagination would be very useful. And might be nice to be able to do: /people?knows=markus <-- people that know markus (LDA already supports this) /people?^knows=markus <-- people that markus knows (^ to indicate traversing link in inverse direction) And be able to make all of these easily discoverable from /person/markus and allow a machine to understand what the list is a list of. Could even imagine support for property paths, but that is another topic. Regards, John > On March 31, 2014 at 10:34 AM Ruben Verborgh <ruben.verbo...@ugent.be> wrote: > > > Dear all, > > Sorry for hacking the discussion, but I think we should keep the discussion > goal-focused. > So let's therefore see what we want to achieve: > 1. Having a way for clients to find out the members of a specific collection > 2. Not breaking the RDF model while doing so > A solution that satisfies 1 and 2 with minimal effort is good enough for > Hydra; > the rest can be discussed more deeply in other places. > > The easiest solution I could come up with that satisfies the above criteria is > the following. > Suppose a client needs to find Markus' friends, and the server use foaf:knows > for that > (which has the restrictive range foaf:Person, disallowing a collection). > If the representation contains all of Markus' friends, then it could look > like: > > </people/markus> foaf:knows </people/Anna>. > </people/markus> foaf:knows </people/Bert>. > </people/markus> foaf:knows </people/Carl>. > > Now, more interestingly, if the list of Markus' friends is available > as a separate resource /people/markus/friends, then it could look like: > > </people/markus> foaf:knows [ hydra:memberOf </people/markus/friends> ]. > > So we say that a blank node is one of Markus' friends, and where it can be > found. > This satisfies 1, because the client can follow the link and find all friends > there. > This satisfies 2, because the blank node is an actual person, not a > collection. > And that is all we need for hypermedia clients to work. > > Yes, I know this does not add a whole bunch of extensive semantics > we might need for specific case X, but: > a) that's not necessary in general; a Hydra client has all it needs; > b) this solution is extensible to allow for that. > If you like, you can add details about /people/markus/friends, > say that they all have a foaf:knows relationship to /people/markus etc. > > Summarized: look at the minimum client needs, implement that; > only thing we need is a blank node and a memberOf predicate. > Hydra clients work; the model is happy too. > > Best, > > Ruben > > PS The only case this slightly breaks the model is if Markus has no friends > yet; > then you say Markus knows somebody while he actually doesn't. > But saying something doesn't exists is a problem in RDF anyway. > The easy way: just don't include any foaf:knows triple (or ignore slight > breakage). > > If you insist to include _something_, we'd need to do have an explicit empty > list: > </people/markus> foaf:knowsList (). > foaf:knowsList hydra:listPropertyOf foaf:knows. > But then we'd be stuck with twice as many properties, which is not ideal > either.