ISSUE-58: the simple solution to inlined membership

Hi, 

      During today's teleconference discussing this issue I suddenly 
realised that there is a  futher solution to those presented here, which 
I think is both simpler and can be applied much more widely: that is to 
all linked data.

  So first of all it turns out that there are good arguments for the use cases
of A and B/C . The current proposals end up requiring the creation of two
new relations. This is problematic because linked data consumers need to
know about these relations. That is a Linked Data Client instead of just having
to make the following query on an LDPC named ldpc

   val members =  ldpc/rdf.member

It now has to also do something like the following

val members = if ( (ldpc/membersInlined).contains("true") )  
                              ldpc/ldp.memberInlined
                         else {
                             val local = ldpc/ldp.memberInlined 
                             val remote = (ldpc/rdf.member - local).map( _.follow )
                             local union remote
                          }

( much more complex that this to tell you the truth )

What is problematic about this is that it would only work for LDPCs, and one could
easily imagine that each LDP service would develop its own version making code
unecessarily difficult.

But I have to explain the simple solution to make it clear why I can use "unecessarily 
difficult": the simple answer is that RDF already comes with the tools to make distinguish
nodes one can follow and nodes one cannot: the blank node! So I propose that for resources
where all the data is contained locally you do the following

<> a ldp:Container;
   rdf:member [ atom:title "Atom Robots Run Amock" ;
                         atom:summary "Atom Robots having drunk a triple espresso semantic powerade....";
                         atom:content " ...." ; 
                         atom:id "http://news.example/2013/05/13/atomRobots"^^xsd:anyURI;
                         atom:updated "2013-05-13..."^^xsd:dateTime;
                       ],
                       [ atom:title "Semantic Revolution in the Blogosphere";
                         atom:summary "it all makes sense!";
                         atom:id "http://news.example/2013/05/12/semanticRevolution"^^xsd:anyURI;
                         ...
                       ] .

So here it is no way to follow the LDPC members, and the ids are not URIs in use
either. If you do want to also allow people to follow the links you can use owl:sameAs or perhaps
the rel=self relation from atom

<> a ldp:Container;
   rdf:member [ atom:title "Atom Robots Run Amock" ;
                         atom:summary "Atom Robots having drunk a triple espresso semantic powerade....";
                         atom:content " ...." ; 
                         atom:self <atomRobots>;
                         atom:updated "2013-05-13..."^^xsd:dateTime;
                       ],
                       [ atom:title "Semantic Revolution in the Blogosphere";
                         atom:summary "it all makes sense!";
                         atom:self <semanticRevolution>;
                         ...
                       ] .


Finally for members where the data should be followed first rather than later

<> a ldp:Container;
   rdf:member <atomRobots>,  <semanticRevolution> .

# a bit of extra data for people arriving on this resource using simpler tools...

<atomRobots> atom:title "Atom Robots Run Amock" ;
                         atom:summary "Atom Robots having drunk a triple espresso semantic powerade....";
                         atom:updated "2013-05-13..."^^xsd:dateTime .
                       
<semanticRevolution> atom:title "Semantic Revolution in the Blogosphere";
                         atom:summary "it all makes sense!" .

The advantage of this is that one can write clients that follow links automatically ( with 
cleverly built cashes to avoid fetching ontologies such as foaf or DC of course ) 
so that as far as possible they always  go to the source of the data, where the information
is defined. When a server does not wish this to happen the server can simply use the blank
node thereby simply stopping the possiblity of getting further information!  The atom:self type
relation or owl:sameAs then gives a way for the server to express that all the data is available
remotely at that location.  

This way we have an answer that works for all LDP resources and we can write generic
code without having to make special corner cases for each type of resource we come across.


Henry

On 30 Apr 2013, at 20:51, Arnaud Le Hors <lehors@us.ibm.com> wrote:

> Looking back at what has been said on this issue, I see several possible paths forward: 
> 
> Option A: Richard's original proposal (without all the details): 
> 
> Add to ldp:Container a boolean property which, when true, indicates that a complete description of all the members is inlined in the container document. 
> 
> Option B: 
> 
> Add to ldp:Container a property ldp:memberInlined which indicates the members for which a complete description is inlined in the container document. 
> 
> Option C: 
> 
> Add a boolean property ldp:memberInlined which, when true, indicates that a complete description of that member is inlined in the container document. 
> 
> Option D: 
> 
> Add a repeatable HTTP Header, such as X-Cacheable-for, which when set to a member URI means that a complete description of that member is inlined in the container document. 
> 
> 
> Here are some examples for each options: 
> 
> Option A: 
> 
> # The following is the representation of
> #                  http://example.org/netWorth/nw1
> @prefix dcterms: <http://purl.org/dc/terms/>.
> @prefix ldp:      <http://www.w3.org/ns/ldp#>.
> @prefix o:       <http://example.org/ontology/>.
> 
> <>
>   a o:NetWorth, ldp:Container;
>   ldp:membershipPredicate o:asset;
>   o:asset <a1>, <a2>; 
>    ldp:membersInlined true.
> 
> <a1>
>    a o:Stock;
>    o:value 10000.
> <a2>
>    a o:Bond;
>    o:value 20000. 
> 
> 
> Option B: 
> 
> # The following is the representation of
> #                  http://example.org/netWorth/nw1
> @prefix dcterms: <http://purl.org/dc/terms/>.
> @prefix ldp:      <http://www.w3.org/ns/ldp#>.
> @prefix o:       <http://example.org/ontology/>.
> 
> <>
>   a o:NetWorth, ldp:Container;
>   ldp:membershipPredicate o:asset;
>   o:asset <a1>, <a2>; 
>    ldp:memberInlined <a1>, <a2>.
> 
> <a1>
>    a o:Stock;
>    o:value 10000.
> <a2>
>    a o:Bond;
>    o:value 20000. 
> 
> Option C: 
> 
> # The following is the representation of
> #                  http://example.org/netWorth/nw1
> @prefix dcterms: <http://purl.org/dc/terms/>.
> @prefix ldp:      <http://www.w3.org/ns/ldp#>.
> @prefix o:       <http://example.org/ontology/>.
> 
> <>
>   a o:NetWorth, ldp:Container;
>   ldp:membershipPredicate o:asset;
>   o:asset <a1>, <a2>.
> 
> <a1>
>    a o:Stock;
>    o:value 10000; 
>    ldp:memberInlined true.
> <a2>
>    a o:Bond;
>    o:value 20000; 
>    ldp:memberInlined true. 
> 
> Option D: 
> 
> # The following is the representation of
> #                  http://example.org/netWorth/nw1
> @prefix dcterms: <http://purl.org/dc/terms/>.
> @prefix ldp:      <http://www.w3.org/ns/ldp#>.
> @prefix o:       <http://example.org/ontology/>.
> 
> <>
>   a o:NetWorth, ldp:Container;
>   ldp:membershipPredicate o:asset;
>   o:asset <a1>, <a2>.
> 
> <a1>
>    a o:Stock;
>    o:value 10000.
> <a2>
>    a o:Bond;
>    o:value 20000. 
> 
> HTTP Headers: 
> X-Cacheable-for: http://example.org/netWorth/nw1/a1 
> X-Cacheable-for: http://example.org/netWorth/nw1/a2 
> 
> Comments anyone? 
> --
> Arnaud  Le Hors - Software Standards Architect - IBM Software Group

Social Web Architect
http://bblfish.net/

Received on Monday, 13 May 2013 16:25:44 UTC