- 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