- From: Lee Feigenbaum <lee@thefigtrees.net>
- Date: Wed, 08 Jul 2009 14:09:41 -0400
- To: Simon K Johnston <skjohn@us.ibm.com>
- CC: public-rdf-dawg@w3.org
Thanks, Simon.
For those without HTML-friendly email clients, here's the URL to the
document in our mailing list archives:
http://lists.w3.org/Archives/Public/public-rdf-dawg/2009JulSep/att-0040/SPARQL-UProtocol-20090707.html
Lee
Simon K Johnston wrote:
> All, the document(s) that describe our RESTful update protocol
> (mentioned on the WG call two weeks ago) are behind a sign-up on our
> Jazz.net site. So, I extracted the content and ensured it is a
> stand-alone document and removed the Jazz formatting. As it would take a
> while to rehost this on an IBM site without some sort of sign-up
> protection I am posting to the mailing list so that we can at least use
> the archive URL for the attachment as a reference.
>
>
>
> Thanks,
>
> ------------------------------------------------------------------------
>
> /Simon K. Johnston (//_skjohn@us.ibm.com_/ <mailto:skjohn@us.ibm.com>/)
> - STSM, Jazz Foundation Services
> Mobile: //_+1 (919) 200-9973_/ <tel:+1.919.200.9973>/
> Office: //_+1 (919) 595-0786_/ <tel:+1.919.595.0786>/ (tie-line:
> //_268-6838_/ <tel:268.6838>/)
> Blog: //_http://www.ibm.com/developerworks/blogs/page/johnston_// /
>
> ------------------------------------------------------------------------
>
>
> Graph Update Protocol
>
>
> A protocol for updating RDF graphs
>
> This version:
> 2009-07-08.
> Authors:
> Simon Johnston, IBM
> Scott Rich, IBM
>
> Copyright © 2009 IBM Corporation. All Rights Reserved.
>
> ------------------------------------------------------------------------
>
>
> Abstract
>
> This document describes the Graph Update Protocol, an update facility
> for RDF graphs. It uses a derivation of the Atom Publishing Protocol.
> Update operations are performed on a collection of named graphs in a
> Graph Store. Operations are provided to change existing RDF named graphs
> as well as to create and remove named graphs with the Graph Store.
>
>
> Status of This Document
>
> This document is made available by the W3 Consortium for discussion
> only. This indicates no endorsement of its content, nor that the
> Consortium has had any editorial control in it preparation, nor that the
> Consortium has, is, or will be allocating any resources to the issues
> addressed by this document.
>
> This document is based upon the IBM /Jazz Foundation Index Store Update
> API/ <https://jazz.net:443/wiki/bin/view/Main/JFSIndexStoreWriteAPI>, a
> capability described and implemented in the IBM Jazz Foundation for the
> update of the graph store used to index resources stored within a Jazz
> Foundation Server instance.
>
> ------------------------------------------------------------------------
>
>
> Table of Contents
>
> 1. Introduction <#sec_intro>
> 2. The Protocol <#sec_protocol>
> 3. Examples <#sec_examples>
>
>
> 1 Introduction
>
> The Graph Update Protocol is intended to allow the addition, replacement
> or deletion of named graphs from an RDF Graph Store. It is intended to
> be a standard mechanism by which updates to a remote RDF Graph Store can
> be described and transmitted. The Graph Update Protocol is inspired by
> the Atom Publishing Protocol in it's use of HTTP verbs to provide a
> RESTful protocol for managing named graphs in an RDF Graph Store.
>
> The Graph Update Protocol provides the following facilities:
>
> * Insert new graph to an RDF Graph Store.
> * Replace or update a graph within an RDF Graph Store.
> * Delete a graph from an RDF Graph Store.
>
> Related work:
>
> * SPARQL Update: A language for updating RDF graphs
> <http://www.w3.org/Submission/SPARQL-Update/>.
> * the wiki page SparqlUpdateLanguage
> <http://esw.w3.org/topic/SparqlUpdateLanguage> for a related proposal
> * Delta: an ontology for the distribution of differences between RDF
> graphs <http://www.w3.org/DesignIssues/Diff>
>
>
> 1.1 Background
>
> The specification presented here is for a RESTful API for updating
> graphs within an RDF Graph Store. The intent is to allow a programmatic
> client the ability to create new graphs, update, replace and delete
> existing graphs using a simple HTTP binding.
>
> In this specification the following definitions shall be used.
>
> Client
> A programmatic client sending messages to the RDF Graph Store using
> the protocol described herein.
> RDF Graph Store
> Like an RDF Dataset operated on by SPARQL, a Graph Store zero or
> more named graphs, but /does not/ have an unnamed graph. Unlike an
> RDF dataset, named graphs can be added or deleted to a graph store.
> Server
> Some service providing an implementation of the protocol described
> herein.
>
>
> 1.2 Document Conventions
>
> Examples are shown in the following format, note that the preceding ">"
> indicates a message from client to the server and the "<" indicates
> response back to the client.
>
>> POST /graphstore/update HTTP/1.1
>> Host: client.example.com
>> Date: 12-02-2008T18:42:00
>> Content-Type: text/plain
>> Content-Length: 83
>>
>> <http://example.com/res.rdf> <http://purl.org/dc/terms/title> "My Resource" .
>
> < HTTP/1.1 201 CREATED
> < Date: 12-02-2008T18:42:30
> < Content-Length: 0
> < Location: /graphstore/update/12-02-2008T18:42:30
>
>
> 2 The Protocol
>
> The Graph Update Protocol supports the insertion of a new Named Graph
> into the Graph Store using the HTTP POST method to a store-specific URI,
> returning a new URI identifying the graph in the graph store. The
> protocol then allows operations on this named graph using standard HTTP
> methods against the URI returned from the creation action.
>
> The URI for the graph store is obviously implementation and installation
> specific, in the specification below we will use the URI template
> |{graph-store}| instead of a specific URI. Similarly the URI for a
> particular graph managed by the graph store is specific and the template
> |{graph-uri}| will be used.
>
>
> 2.1 Protocol Overview
>
> The following table summarizes the methods used to manage graphs in the
> graph store. Note that those methods marked in /italics/ are optional, a
> server may or may not provide these methods however all other methods
> must be provided and must be implemented according to the required
> features of the protocol described in the sections below.
>
> Method URI Comments
> |POST| |{graph-store}| Inserts a graph into the store.
> |*| |{graph-store}| Not permitted - returns 405 (Method not allowed).
> |/GET/| |{graph-uri}| Retrieve the graph identified by the URI.
> |HEAD| |{graph-uri}| Retrieve the headers for the graph identified by
> the URI.
> |PUT| |{graph-uri}| Replace the graph identified by the URI.
> |/PATCH/| |{graph-uri}| Update the graph identified by the URI.
> |DELETE| |{graph-uri}| Delete the graph identified by the URI.
> |*| |{graph-uri}| Not permitted - returns 405 (Method not allowed).
>
>
> 2.2 Insert Graph
>
> Inserting a graph is performed using an HTTP POST method against the
> |{graph-store}| URI. A client may provide a value to the server to help
> construct the URI for the new graph in the HTTP |Graph| request header
> (this is similar to the |Slug| or |Name| header described in the Atom
> Publishing Protocol). The server is at liberty to create a URI of any
> reasonable form, but unique for any successfully created graph. This
> resulting URI is returned to the client in the HTTP |Location| response
> header. If the client does not provide a |Graph| header on the request
> the server may use any reasonable value in constructing the graph URI.
> Therefore the |Graph| header is optional in a request, however the
> |Location| header is required in the response.
>
> The graph to insert is included as the body of the HTTP message and may
> be provided in any reasonable representation the server can process
> (e.g. N-Triples, Turtle, N3, RDF/XML), and the representation is
> identified by the client using the standard HTTP |Content-Type| request
> header. If the representation cannot be processed by the server the
> server must respond with a 415 error, otherwise it should be parsed and
> processed. If the server fails to parse the message body, i.e. the
> server accepted the value of the |Content-Type| header but the body was
> not a legal resource according to that type, then the server must
> respond with a 400 error.
>
> To allow for concurrent modification checks the server must also provide
> a valid HTTP |ETag| response header in the response to a creation request.
>
> The expected responses possible from the graph store are therefore:
>
> 201 (Created)
> The graph was successfully added to the graph store. The graph store
> will return a URI in the HTTP |Location| header that identifies the
> newly inserted graph.
> 400 (Bad Request)
> This error may be returned because either a |Graph| header was
> provided that already exists or the message body could not be parsed
> as a legal representation of a graph.
> 415 (Unsupported Media Type)
> The required |Content-Type| HTTP header identifies a representation
> that cannot be handled by the graph store.
>
>
> 2.3 Retrieve Graph
>
> Retrieving a graph is an optional feature of the protocol, it may not be
> possible for the server to construct and return the complete contents of
> a named graph in an appropriate manner, and as this protocol is intended
> to be used in conjunction with the standard SPARQL protocol the graph
> should be retrievable using standard SPARQL queries. However, it must be
> possible to retrieve the current |ETag| value for a named graph and so
> while the GET method is optional a server must support the use of HEAD
> on a |{graph-uri}| which will return the HTTP |ETag| response header.
>
> Where a server implements the GET method it may also, optionally,
> provide content-negotiation in the standard HTTP manner using a
> client-specified HTTP |Accept| request header. This allows for the
> client to specify the particular representation(s) it would prefer and
> the server can then pick the most appropriate representation to return.
> If a server provides this feature then the error 415 identifies the case
> that no requested representation can be provided by the server.
>
> The expected responses possible from the graph store are therefore:
>
> 200 (OK)
> The request was successful;
> If the method was HEAD then the response will at least contain the
> HTTP |ETag| response header,
> If the method was GET then the response will at least contain the
> HTTP |ETag|, |Content-Type| and |Content-Length| response header as
> well as the graph represented in a form compatible with the client's
> specified HTTP |Accept| request header.
> 404 (Not Found)
> The |{graph-uri}| specified does not identify a named graph in the
> graph store.
> 410 (Gone)
> The |{graph-uri}| specified identifies a named graph that has been
> removed from the graph store. This is an optional response, if the
> server is able to track deleted graphs then this response should be
> used, else the server should respond with 404.
> 415 (Unsupported Media Type)
> The client provided an HTTP |Accept| request header that cannot be
> satisfied by the server to create a valid response.
>
>
> 2.4 Replace Graph
>
> Replacing a graph is performed using an HTTP PUT method against the
> |{graph-store}| URI. The body of the request method is a valid graph
> representation (see section 2.2 above), and the current value of the
> graph will be replaced entirely by the graph provided in the request.
>
> The server must provide for concurrent modification protection,
> specifically using entity tag values on all update requests. This
> requires the client to provide an entity tag in either an HTTP
> |If-Match| or |If-None-Match| request header which is returned by the
> server on all update methods or by retrieving the graph (using either
> GET or HEAD).
>
> The expected responses possible from the graph store are therefore:
>
> 200 (OK)
> The request was successful, the response must contain a value for
> the HTTP |ETag| response header.
> 400 (Bad Request)
> The request was either:
> did not contain either an HTTP |If-Match| or |If-None-Match| request
> header, or
> did not contain a message body (graph representation) at all, or
> the message body could not be parsed as a legal representation of a
> graph.
> 404 (Not Found)
> The |{graph-uri}| specified does not identify a named graph in the
> graph store.
> 409 (Conflict)
> The entity tag information provided in either the HTTP |If-Match| or
> |If-None-Match| request header does not match the current value for
> the graph. This implies that the graph has been concurrently
> modified between the time the client retrieved the entity tag for
> the graph and this attempt to update it.
> 410 (Gone)
> The |{graph-uri}| specified identifies a named graph that has been
> removed from the graph store. This is an optional response, if the
> server is able to track deleted graphs then this response should be
> used, else the server should respond with 404.
> 415 (Unsupported Media Type)
> The client provided an HTTP |Accept| request header that cannot be
> satisfied by the server to create a valid response.
>
>
> 2.5 Update Graph
>
> Updating a graph is an optional feature, performed using an HTTP PATCH
> method against the |{graph-store}| URI. If supported the server must
> accept some representation that allows for the identification of the
> difference between the existing state of the graph and the expected end
> state; for example the Delta ontology.
>
> The server must provide for concurrent modification protection,
> specifically using entity tag values on all update requests. This
> requires the client to provide an entity tag in either an HTTP
> |If-Match| or |If-None-Match| request header which is returned by the
> server on all update methods or by retrieving the graph (using either
> GET or HEAD).
>
> The expected responses possible from the graph store are therefore:
>
> 200 (OK)
> The request was successful, the response must contain a value for
> the HTTP |ETag| response header.
> 400 (Bad Request)
> The request was either:
> did not contain either an HTTP |If-Match| or |If-None-Match| request
> header, or
> did not contain a message body (graph representation) at all, or
> the message body could not be parsed as a legal representation of a
> graph diff.
> 404 (Not Found)
> The |{graph-uri}| specified does not identify a named graph in the
> graph store.
> 409 (Conflict)
> The entity tag information provided in either the HTTP |If-Match| or
> |If-None-Match| request header does not match the current value for
> the graph. This implies that the graph has been concurrently
> modified between the time the client retrieved the entity tag for
> the graph and this attempt to update it.
> 410 (Gone)
> The |{graph-uri}| specified identifies a named graph that has been
> removed from the graph store. This is an optional response, if the
> server is able to track deleted graphs then this response should be
> used, else the server should respond with 404.
>
>
> 2.6 Delete Graph
>
> Deleting a graph is performed using an HTTP DELETE method against the
> |{graph-store}| URI. No body should be provided in the request, which
> also implies that no HTTP |Content-Type| or |Content-Length| request
> headers; if these are provided they will be ignored.
>
> The server must provide for concurrent modification protection,
> specifically using entity tag values on all update requests. This
> requires the client to provide an entity tag in either an HTTP
> |If-Match| or |If-None-Match| request header which is returned by the
> server on all update methods or by retrieving the graph (using either
> GET or HEAD).
>
> The expected responses possible from the graph store are therefore:
>
> 200 (OK)
> The request was successful, the response must contain a value for
> the HTTP |ETag| response header.
> 400 (Bad Request)
> The request did not contain either an HTTP |If-Match| or
> |If-None-Match| request header.
> 404 (Not Found)
> The |{graph-uri}| specified does not identify a named graph in the
> graph store.
> 409 (Conflict)
> The entity tag information provided in either the HTTP |If-Match| or
> |If-None-Match| request header does not match the current value for
> the graph. This implies that the graph has been concurrently
> modified between the time the client retrieved the entity tag for
> the graph and this attempt to update it.
> 410 (Gone)
> The |{graph-uri}| specified identifies a named graph that has been
> removed from the graph store. This is an optional response, if the
> server is able to track deleted graphs then this response should be
> used, else the server should respond with 404.
>
>
> 2.7 Security Responses
>
> Exposing RDF data for update creates many security issues which any
> deployment must be aware of, and consider the risks involved. While this
> specification does not provide a detailed security specification it is
> expected that servers provide mechanisms for authentication of users and
> authorizations of update actions.
>
> While the details of implementation are out of scope of this
> specification it is expected that servers make use of the standard HTTP
> authentication mechanism and associated error codes listed below:
>
> 401 (Unauthorized)
> The server requires clients to be authenticated before update
> operations may be performed, the client request has not provided
> authentication headers.
> 403 (Forbidden)
> The authenticated user does not have permission to perform the
> requested operation.
>
>
> 3 Examples
>
> In the following examples the URI templates described above have the
> following values where {identifier} is either taken from the
> client-provided |Graph| request header, or assigned by the server.
>
> * |{graph-store}| - |http://example.com/graphstore/update|
> * |{graph-uri}| - |http://example.com/graphstore/graph/{identifier}|
>
>
> 3.1 Inserting Graph with Explicit Identifier
>
> The following example demonstrates the client requesting the insertion
> of a graph into the graph store providing an explicit value to be used
> for the graph identifier.
>
>> POST /graphstore/update HTTP/1.1
>> Host: client.example.com
>> Date: 12-02-2008T18:42:00
>> Content-Type: text/plain
>> Content-Length: 83
>> Graph: my-resource
>>
>> <http://example.com/res.rdf> <http://purl.org/dc/terms/title> "My Resource" .
>
> < HTTP/1.1 201 CREATED
> < Date: 12-02-2008T18:42:30
> < Location: http://example.com/graphstore/graph/my-resource
> < ETag: "8726363623523"
>
> * The client is providing an explicit identifier, "my-resource" to
> the server using the |Graph| request header.
> * The client is providing a graph in the request body with an
> N-Triples representation and setting the HTTP |Content-Type|
> request header to the corresponding "text/plain" value.
> * The server responds with the status code 201, the new graph has
> been inserted.
> * The server provides, in the HTTP |Location| response header, the
> URI of the newly created graph.
> * The server provides, in the HTTP |ETag| response header, the
> entity tag value of the the newly created graph.
>
> Alternatively the client could have left out the |Graph| request header
> and the server would have created and used some unique value in the
> place of "my-resource" in the resulting URI.
>
>
> 3.2 Replacing a Graph
>
> The following example demonstrates an attempt to replace the graph
> created above, however the client has specified the wrong graph URI in
> the request.
>
>> PUT /graphstore/graph/my-bad-resource HTTP/1.1
>> Host: client.example.com
>> Date: 12-02-2008T18:42:00
>> Content-Type: text/plain
>> Content-Length: 83
>>
>> <http://example.com/res.rdf> <http://purl.org/dc/terms/title> "New Resource" .
>
> < HTTP/1.1 404 NOT FOUND
>
> The following example uses the correct URI now but does not include the
> entity tag value used to ensure that the request takes concurrent
> modification into account.
>
>> PUT /graphstore/graph/my-resource HTTP/1.1
>> Host: client.example.com
>> Date: 12-02-2008T18:42:00
>> Content-Type: text/plain
>> Content-Length: 83
>>
>> <http://example.com/res.rdf> <http://purl.org/dc/terms/title> "New Resource" .
>
> < HTTP/1.1 400 BAD REQUEST
>
> The following example uses the correct URI now but includes an invalid
> entity tag value.
>
>> PUT /graphstore/graph/my-resource HTTP/1.1
>> Host: client.example.com
>> Date: 12-02-2008T18:42:00
>> Content-Type: text/plain
>> Content-Length: 83
>> If-Match: "1111111111111"
>>
>> <http://example.com/res.rdf> <http://purl.org/dc/terms/title> "New Resource" .
>
> < HTTP/1.1 409 CONFLICT
>
> The following example specifies a complete and correct request.
>
>> PUT /graphstore/graph/my-resource HTTP/1.1
>> Host: client.example.com
>> Date: 12-02-2008T18:42:00
>> Content-Type: text/plain
>> Content-Length: 83
>> If-Match: "8726363623523"
>>
>> <http://example.com/res.rdf> <http://purl.org/dc/terms/title> "New Resource" .
>
> < HTTP/1.1 200 OK
> < Date: 12-02-2008T18:44:22
> < ETag: "8726343622134"
>
> * The client specifies a correct value for the HTTP |If-Match|
> request header.
> * The client is providing a graph in the request body with an
> N-Triples representation and setting the HTTP |Content-Type|
> request header to the corresponding "text/plain" value.
> * The server responds with the status code 200, the graph has been
> replaced.
> * The server provides, in the HTTP |ETag| response header, the
> entity tag value of the the updated graph.
>
>
> 3.3 Retrieving Graph HTTP Headers
>
> The following example shows how the HTTP HEAD method can be used to
> retrieve the entity tag value, required for update requests.
>
>> HEAD /graphstore/graph/my-resource HTTP/1.1
>> Host: client.example.com
>> Date: 12-02-2008T18:42:00
>
> < HTTP/1.1 200 OK
> < Date: 12-02-2008T18:44:22
> < ETag: "8726343622134"
>
> Our example server does support the required HEAD method as shown above,
> but does not support the optional GET method. When the client issues a
> GET method the server responds with the 405 error message as described
> in the specification above.
>
>> GET /graphstore/graph/my-resource HTTP/1.1
>> Host: client.example.com
>> Date: 12-02-2008T18:42:00
>
> < HTTP/1.1 405 METHOD NOT ALLOWED
>
>
> 3.4 Deleting a Graph
>
> The following example demonstrates a request to delete the resource
> shown in the examples so far.
>
>> DELETE /graphstore/graph/my-bad-resource HTTP/1.1
>> Host: client.example.com
>> Date: 12-02-2008T18:42:00
>
> < HTTP/1.1 200 OK
>
> Note that in this case no HTTP |ETag| response header is provided, the
> graph has been deleted and therefore has no state that can be
> represented by an entity tag.
>
> Our example server keeps track of graphs that have been deleted,
> therefore if the client attempts to perform another HEAD on the graph
> the server is able to return 410 instead of the more general 404.
>
>> HEAD /graphstore/graph/my-resource HTTP/1.1
>> Host: client.example.com
>> Date: 12-02-2008T18:42:00
>
> < HTTP/1.1 410 GONE
>
>
> References
>
> [SPARQL-P]
> SPARQL Protocol for RDF <http://www.w3.org/TR/rdf-sparql-protocol/>,
> Kendall Clark, Lee Feigenbaum, Elias Torres (editors), W3C
> Recommendation.
> [SPARQL-Q]
> SPARQL Query Language for RDF
> <http://www.w3.org/TR/rdf-sparql-query/>, Eric Prud'hommeaux, Andy
> Seaborne (editors), W3C Recommendation.
> [SPARQL-R]
> SPARQL Query Results XML Format
> <http://www.w3.org/TR/rdf-sparql-XMLres/> , D. Beckett (editor), W3C
> Recommendation.
> [RFC2616]
> RFC 2616 Hypertext Transfer Protocol -- HTTP/1.1
> <http://www.ietf.org/rfc/rfc2616.txt>, R. Fielding, J. Gettys, J.
> Mogul, H. Frystyk, L. Masinter, P. Leach, T. Berners-Lee.
> [RFC3986]
> RFC 3986 Uniform Resource Identifier (URI): Generic Syntax
> <http://www.ietf.org/rfc/rfc3986.txt>, T. Berners-Lee, R. Fielding,
> L. Masinter.
> [RFC3987]
> RFC 3987 Internationalized Resource Identifiers (IRIs)
> <http://www.ietf.org/rfc/rfc3987.txt>, M. Dürst , M. Suignard.
> [RFC5023]
> RFC 5023 The Atom Publishing Protocol
> <http://www.ietf.org/rfc/rfc5023.txt>, J. Gregorio, B. de hOra.
> [UNICODE]
> The Unicode Standard, Version 4. ISBN 0-321-18578-1, as updated from
> time to time by the publication of new versions. The latest version
> of Unicode and additional information on versions of the standard
> and of the Unicode Character Database is available at
> http://www.unicode.org/unicode/standard/versions/.
> [URI-T]
> URI Template
> <http://tools.ietf.org/html/draft-gregorio-uritemplate-03>, J.
> Gregorio, M. Hadley, M. Nottingham, D. Orchard.
>
>
>
Received on Wednesday, 8 July 2009 18:10:44 UTC