- From: Sandro Hawke <sandro@w3.org>
- Date: Sat, 07 Sep 2013 22:57:58 -0400
- To: David Wood <david@3roundstones.com>
- CC: public-ldp-patch@w3.org
- Message-ID: <522BE7B6.4030002@w3.org>
On 09/07/2013 10:39 PM, Sandro Hawke wrote:
> Thanks for something so concrete, Dave. For myself, much of the
> challenge here is that I've not had time to implement, so it remains
> too abstract. Some questions and thoughts, inline....
>
> On 09/07/2013 09:09 PM, David Wood wrote:
>> Hi all,
>>
>> The need for a PATCH format for LDP was brought up again in last
>> week's meeting with TimBL [1]. To summarize briefly, Tim made the
>> point that LDP has no generic way to update data without a PATCH
>> format and Arnaud said that the WG wanted one but hadn't yet been
>> able to define it. Arnaud called for a halt on PATCH formats in May [2]
>>
>> The two main approaches would seem to be Andy's proposal [3] which
>> uses basic triple patterns to define what to add or remove from a
>> store and Sandro's TurtlePatch [4].
>>
>
> I also did a Trig-based patch format, DataPatch:
> http://www.w3.org/People/Sandro/datapatch but like TurtlePatch I
> haven't actually been pushing it. But it was going the direction
> the WG said it wanted to go, using TriG.
>
Oh, also datapatch has a bunch of stuff that's been obsoleted by RDF 1.1
being more clear about who literals match, right after I wrote it.
-- Sandro
>> This message suggests a third approach based on a strictly defined
>> subset of SPARQL Update
>
> Isn't that exactly what TurtlePatch was? True, your subset is
> somewhat..
>
>> . Our approach is already implemented in the (Apache 2 licensed)
>> Callimachus Project [5] and documented later in this message. Henry
>> has already mentioned that a subset of SPARQL Update could work [6]
>> for the WG's purposes.
>>
>> A strict subset of SPARQL Update is used in the Callimachus
>> implementation to support the following constructs in a
>> PATCH request. However, each clause can only contain zero or more
>> basic graph patterns and only the default graph can be used.
>> * DELETE DATA
>> * INSERT DATA
>> * DELETE WHERE
>> * INSERT WHERE
>> * DELETE INSERT WHERE
>>
>> Callimachus further restricts the SPARQL Update spec such that all
>> nodes are connected and all URIs, in the subject position, before a
>> '#' (if present), are the same.
>>
>
> What's the reasoning behind this? I've always assumed that a basic
> requirement of Patch was that it be able to patch any RDF graph to any
> other RDF graph (given enough computing resources). Is there some
> other requirement that necessitates this restriction?
>
> -- Sandro
>
>> Callimachus enforces this by walking the syntax tree of the
>> parsed SPARQL Update request and flags any construct that does fit
>> with the above. Callimachus uses the Sesame query model, which is a
>> bit different than the SPARQRL grammer. The code that walks
>> the SPARQL Update tree and flags constructs that are not explicitly
>> listed is available online at [7].
>>
>> Then it verifies the request body [8] by checking that all URIs
>> in the subject position (before '#') are the same [9], all nodes are
>> connected [10], all present constructs are permitted[7], and finally
>> it makes sure no blank nodes are left disconnected[11].
>>
>> To try this out, fire up a Callimachus instance and run the follow
>> curl commands:
>>
>> ################################
>> # Discover the LDPR of the root resource by looknig for rel="describedby"
>> ################################
>> $ curl -iX OPTIONS http://localhost:8080/
>>
>> HTTP/1.1 204 No Content
>> Allow: OPTIONS, TRACE, GET, HEAD, POST, PATCH, DELETE, PUT
>> Access-Control-Allow-Methods: OPTIONS, TRACE, GET, HEAD, POST, PATCH,
>> DELETE, PUT
>> Access-Control-Allow-Headers:
>> Accept,Accept-Charset,Accept-Encoding,Accept-Language,Authorization,Cache-Control,Content-Encoding,Content-Language,Content-Length,Content-Location,Content-MD5,Content-Type,If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since,Location,Range,Cookie,Referer,Slug
>> Link: <http://localhost:8080/?discussion>; rel="comments";
>> type="text/html"
>> Link: <http://localhost:8080/?search>; rel="search";
>> type="application/opensearchdescription+xml"
>> Link: <http://localhost:8080/?describe>; rel="describedby";
>> type="text/html application/rdf+xml;q=0.4 text/turtle;q=0.5";
>> title="RDF Describe"
>> Link: <http://localhost:8080/?realms>;
>> rel="http://callimachusproject.org/rdf/2009/framework#realms";
>> type="application/atom+xml;q=0.9"
>> Link: <http://localhost:8080/?contents>; rel="contents";
>> type="application/atom+xml;q=0.9"
>> Link: <http://localhost:8080/?edit>; rel="edit-form"; type="text/html"
>> Link: <http://localhost:8080/?history>; rel="version-history";
>> type="text/html application/atom+xml;q=0.9"
>> Link: <http://localhost:8080/?view>; rel="alternate"; type="text/html"
>> Link: <http://localhost:8080/?archive>;
>> rel="http://callimachusproject.org/rdf/2009/framework#archive"
>> Link: <http://localhost:8080/?changes>; rel="alternate"; type="text/html"
>> Cache-Control: public
>> Vary: Accept
>> Vary: Origin
>> Vary: Access-Control-Request-Method
>> Content-Version: "/callimachus/changes/2013/09/05/t140ee789cecx1971"
>> ETag: W/"216e0b6d-a038f4fe"
>> Last-Modified: Thu, 05 Sep 2013 15:59:13 GMT
>> Access-Control-Allow-Origin: http://localhost:8080
>> Access-Control-Expose-Headers: Content-Length, Allow,
>> Access-Control-Allow-Methods, Access-Control-Allow-Headers, Link,
>> Cache-Control, Vary, Content-Version, ETag, Last-Modified,
>> Access-Control-Allow-Origin, Content-Type, Content-Encoding, Date, Server
>> Date: Thu, 05 Sep 2013 16:55:48 GMT
>> Server: Callimachus/1.2-beta-10
>>
>>
>> ################################
>> # Create a new resource, by POSTing the RDF as sparql-update
>> ################################
>> $ curl -i --digest --user james --data-binary @- -H
>> content-type:application/sparql-update http://localhost:8080/?describe
>> BASE <http://localhost:8080/>
>> PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
>> INSERT DATA {
>> <sun> a skos:Concept, </callimachus/1.0/types/Concept> ;
>> skos:prefLabel "Sun" ;
>> skos:definition "The great luminary" .
>> }
>>
>> HTTP/1.1 201 Created
>> Location: http://localhost:8080/sun
>> Content-Version: "/callimachus/changes/2013/09/05/t140ee789cecx2216"
>> Derived-From: "/callimachus/changes/2013/09/05/t140ee789cecx2190"
>> ETag: W/"216e64d0-62cbb087"
>> Content-Type: text/uri-list;charset=UTF-8
>> Access-Control-Allow-Origin: http://localhost:8080
>> Access-Control-Expose-Headers: Location, Content-Version,
>> Derived-From, ETag, Content-Type, Access-Control-Allow-Origin,
>> Content-Length, Content-Encoding, Date, Server
>> Date: Thu, 05 Sep 2013 17:02:45 GMT
>> Content-Length: 25
>> Content-Encoding: identity
>> Server: Callimachus/1.2-beta-10
>>
>> http://localhost:8080/sun
>>
>>
>> ################################
>> # Discover the LDPR of the newly created resource
>> ################################
>> $ curl -iX OPTIONS http://localhost:8080/sun
>>
>> HTTP/1.1 204 No Content
>> Allow: OPTIONS, TRACE, POST, PATCH, GET, HEAD, DELETE
>> Access-Control-Allow-Methods: OPTIONS, TRACE, POST, PATCH, GET, HEAD,
>> DELETE
>> Access-Control-Allow-Headers:
>> Accept,Accept-Charset,Accept-Encoding,Accept-Language,Authorization,Cache-Control,Content-Encoding,Content-Language,Content-Length,Content-Location,Content-MD5,Content-Type,If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since,Location,Range
>> Link: <http://localhost:8080/sun?history>; rel="version-history";
>> type="text/html application/atom+xml;q=0.9"
>> Link: <http://localhost:8080/sun?discussion>; rel="comments";
>> type="text/html"
>> Link: <http://localhost:8080/sun?describe>; rel="describedby";
>> type="text/html application/rdf+xml;q=0.4 text/turtle;q=0.5";
>> title="RDF Describe"
>> Link: <http://localhost:8080/sun?edit>; rel="edit-form"; type="text/html"
>> Link: <http://localhost:8080/sun?view>; rel="alternate"; type="text/html"
>> Cache-Control: public
>> Vary: Accept
>> Vary: Origin
>> Vary: Access-Control-Request-Method
>> Content-Version: "/callimachus/changes/2013/09/05/t140ee789cecx2216"
>> ETag: W/"216e64d0"
>> Last-Modified: Thu, 05 Sep 2013 17:02:45 GMT
>> Access-Control-Allow-Origin: http://localhost:8080
>> Access-Control-Expose-Headers: Content-Length, Allow,
>> Access-Control-Allow-Methods, Access-Control-Allow-Headers, Link,
>> Cache-Control, Vary, Content-Version, ETag, Last-Modified,
>> Access-Control-Allow-Origin, Content-Type, Content-Encoding, Date, Server
>> Date: Thu, 05 Sep 2013 17:03:44 GMT
>> Server: Callimachus/1.2-beta-10
>>
>>
>> ################################
>> # Now update the resource using a subset of sparql-update
>> ################################
>> $ curl --digest --user james -X PATCH --data-binary @- -H
>> content-type:application/sparql-update http://localhost:8080/sun?describe
>> PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
>> DELETE DATA {
>> </sun> skos:definition "The great luminary" .
>> };
>> INSERT DATA {
>> </sun> skos:definition "The lamp of day" .
>> };
>>
>> HTTP/1.1 204 No Content
>> Content-Version: "/callimachus/changes/2013/09/05/t140ee789cecx2245"
>> Derived-From: "/callimachus/changes/2013/09/05/t140ee789cecx2241"
>> ETag: W/"216e652c-469953d3"
>> Access-Control-Allow-Origin: http://localhost:8080
>> Access-Control-Expose-Headers: Content-Length, Content-Version,
>> Derived-From, ETag, Access-Control-Allow-Origin, Content-Type,
>> Content-Encoding, Date, Server
>> Date: Thu, 05 Sep 2013 17:05:48 GMT
>> Server: Callimachus/1.2-beta-10
>>
>>
>> With the above, you can try out these other requests below.
>>
>> The following are some examples of valid PATCH requests:
>>
>>
>> PATCH /sun?describe HTTP/1.1
>> Host: localhost:8080
>> Content-Type:application/sparql-update
>> Transfer-Encoding: identity
>>
>> BASE <http://localhost:8080/>
>> PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
>> DELETE DATA {
>> </sun> skos:definition "The great luminary" .
>> };
>> INSERT DATA {
>> </sun> skos:definition "The lamp of day" .
>> };
>>
>>
>> PATCH /sun?describe HTTP/1.1
>> Host: localhost:8080
>> Content-Type:application/sparql-update
>> Transfer-Encoding: identity
>>
>> BASE <http://localhost:8080/>
>> PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
>> INSERT DATA {
>> </sun> skos:scopeNode "sun is part of our solar system" .
>> }
>>
>>
>> PATCH /sun?describe HTTP/1.1
>> Host: localhost:8080
>> Content-Type:application/sparql-update
>> Transfer-Encoding: identity
>>
>> BASE <http://localhost:8080/>
>> PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
>> DELETE DATA {
>> </sun> skos:scopeNode "sun is part of our solar system" .
>> };
>> INSERT {
>> </sun> skos:scopeNode ("sun is part of our " <solarSystem>) .
>> } WHERE {};
>>
>>
>> PATCH /sun?describe HTTP/1.1
>> Host: localhost:8080
>> Content-Type:application/sparql-update
>> Transfer-Encoding: identity
>>
>> BASE <http://localhost:8080/>
>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>> PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
>> DELETE WHERE {
>> </sun> skos:scopeNode ?list0 .
>> ?list0 rdf:first "sun is part of our "; rdf:rest ?list1 .
>> ?list1 rdf:first <solarSystem>; rdf:rest rdf:nil .
>> };
>> INSERT {
>> </sun> skos:scopeNode ("sun is in our " <solarSystem>) .
>> } WHERE {};
>>
>>
>> The following requests are INVALID as outlined below.
>>
>> PATCH /sun?describe HTTP/1.1
>> Host: localhost:8080
>> Content-Type:application/sparql-update
>> Transfer-Encoding: identity
>>
>> BASE <http://localhost:8080/>
>> PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
>> DELETE {
>> </sun> skos:definition ?definition .
>> } INSERT {
>> </sun> skos:definition ?newvalue .
>> } WHERE {
>> </sun> skos:definition ?definition .
>> BIND (concat(?definition,"!") AS ?newvalue)
>> };
>>
>> HTTP/1.1 400 Only basic graph patterns are permitted
>>
>>
>> PATCH /sun?describe HTTP/1.1
>> Host: localhost:8080
>> Content-Type:application/sparql-update
>> Transfer-Encoding: identity
>>
>> BASE <http://localhost:8080/>
>> CREATE GRAPH </sun>
>>
>> HTTP/1.1 500 Unsupported type of update statement: Create
>>
>>
>> PATCH /sun?describe HTTP/1.1
>> Host: localhost:8080
>> Content-Type:application/sparql-update
>> Transfer-Encoding: identity
>>
>> BASE <http://localhost:8080/>
>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>> PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
>> DELETE WHERE {
>> </sun> skos:scopeNode ("sun is part of our " <solarSystem>) .
>> };
>> INSERT {
>> </sun> skos:scopeNode ("sun is in our " <solarSystem>) .
>> } WHERE {};
>>
>> HTTP/1.1 500 DELETE WHERE may not contain blank nodes
>>
>>
>> Using a sparql-update grammer parser it was fairly easy to limited the
>> tokens to a subset that can be validated easily, yet useful to the
>> client.
>>
>>
>> Regards,
>> Dave, with massive work by James Leigh
>> --
>> http://about.me/david_wood
>>
>>
>> [1] http://www.w3.org/2013/meeting/ldp/2013-09-03
>> [2] http://lists.w3.org/Archives/Public/public-ldp-wg/2013May/0233.html
>> [3] http://afs.github.io/rdf-patch/
>> [4] http://www.w3.org/2001/sw/wiki/TurtlePatch
>> [5] http://callimachusproject.org
>> [6] http://lists.w3.org/Archives/Public/public-ldp-wg/2013May/0239.html
>> [7]
>> https://code.google.com/p/callimachus/source/browse/tags/1.1.2/src/org/callimachusproject/form/helpers/TripleAnalyzer.java#220
>> [8]
>> https://code.google.com/p/callimachus/source/browse/tags/1.1.2/src/org/callimachusproject/form/helpers/EntityUpdater.java#105
>>
>> [9]
>> https://code.google.com/p/callimachus/source/browse/tags/1.1.2/src/org/callimachusproject/form/helpers/TripleVerifier.java#176
>> [10]
>> https://code.google.com/p/callimachus/source/browse/tags/1.1.2/src/org/callimachusproject/form/helpers/TripleVerifier.java#289
>> [11]
>> https://code.google.com/p/callimachus/source/browse/tags/1.1.2/src/org/callimachusproject/form/helpers/EntityUpdater.java#98
>>
>
Received on Sunday, 8 September 2013 02:58:06 UTC