SPARQL Protocol for RDF

DRAFT: $Id: protocol-wd.html,v 1.2 2004/11/10 15:42:55 k Exp $

Kendall Grant Clark, <kendall@monkeyfist.com>, W3C Data Access Working Group.

Table of Contents

  1. Introduction
  2. Goals, Constraints, and Assumptions
  3. Terminology
    1. Notational Conventions
    2. Domain-specific Terms
  4. Conformance Requirements
    1. Minimal Conformance
    2. Conformance
    3. Maximal Conformance
  5. Abstract Protocol
    1. Types
    2. Responses
    3. Operations
  6. Advertisement and Discovery
  7. Concrete Protocol—HTTP
    1. Basic Types
    2. Response Codes
    3. Operations
    4. Data Passing Conventions
    5. Content Negotiation
    6. Caching
  8. References
  9. Acknowledgments

1. Introduction

The Semantic Web is based in part on RDF, which is a flexible and extensible way to represent, and reason about, information describing World Wide Web resources. The promise of the Semantic Web rests in part on the promise of ad hoc, arbitrary data aggregation and integration. RDF is crucial to this promise, as is a uniform means of interacting with remote or local RDF storage services. At present there are many different methods of accessing remote RDF storage servers; and even in those cases where the basic access protocol is based on an existing standard, there is no consensus about protocol features, extensibility points, service descriptions and advertisements, data-passing conventions, etc.

This document describes SPARQL, a protocol for accessing RDF data and for conveying RDF queries from query clients to query processors. The SPARQL Protocol has been designed for compatability with the SPARQL Query Language for RDF but is designed to convey queries from other RDF query languages as well. In what follows the SPARQL protocol is described in two ways: first, as an abstract protocol independent of any concrete realization, implementation, or binding to another protocol; second, as a concrete protocol implementation based on HTTP. Other concrete realizations of the abstract protocol described herein are encouraged. In order to formalize both the abstract and concrete protocols, as well as describe and advertize the capabilities of SPARQL implementations, we make use of WSDL 2.0, especially its mapping to RDF.

2. Goals, Constraints, and Assumptions

The design of the protocol described in this document is motivated by a set of general principles, constraints, and web best practices, including the W3C Technical Architecture Group's Architecture of the World Wide Web, First Edition and the REST architectural style.

Some of these design goals and constraints include:

  1. Important resources should have URIs. As Architecture of the World Wide Web says, "A resource should have an associated URI if another party might reasonably want to create a hypertext link to it, make or refute assertions about it, retrieve or cache a representation of it, include all or part of it by reference into another representation, annotate it, or perform other operations on it."
  2. Concrete implementations of the abstract protocol described herein should be able to reuse as much of the existing Web as possible.
  3. The most significant resource types in this problem space are RDF graphs, RDF triples, RDF queries, query clients, and query processors.
  4. It is sometimes necessary to query an ad hoc aggregation of RDF graphs—including those owned and controlled by third parties—in situations where the query client cannot coin a stable URI to identify the aggregation.
  5. Every abstract protocol operation should be orthogonal to every other abstract protocol operation.
  6. Conforming implementations should provide RDF descriptions of important query resources.
  7. Conforming client implementations should be as simple to create as possible. If a design tradeoff involves client versus server implementational complexity, the design should arrange the burden of that complexity to rest on conforming server implementations.
  8. The protocol described herein should make as few assumptions and dictate as few constraints on conforming implementations as possible; in particular, the urispace of conforming implementations should be minimally constrained.
  9. SPARQL server deployments will often be modifications of existing systems or will be deployed into existing environments, web services, and applications. There doesn't seem to be a conclusive answer to the question of whether an RDF data access protocol should concern ittself with RDF graphs or with query services. The abstract protocol, thus, should be as agnostic as possible as to whether its operations work on RDF graphs qua REST resources or on RDF query service processors qua SOA endpoints. This agnosticism is intended to allow concrete protocols, and implementations thereof, to adopt either a graph-centric, service-centric, or mixed perspective.
  10. Given the development of RDF, WSDL, and a mapping from the former to the latter, as well as the work done on discovery and advertisement in the Web Services world, it should be possible for a SPARQL client to discover, and for a SPARL server to advertise its, capabilities, features, and implementation details. A SPARQL client should be able to go from, say, an RDF triple like (http://example/qsp, rdf:type, dawg:SparqlQueryProcessor) to interacting with the query service, http://foo.example/bar, in a robust way in a few steps or protocol operations.

3. Terminology

A. Requirements Keywords

When in this document the words must, must not, should, should not, may and recommended appear as emphasized text, they must be interpreted as described in RFC 2119.

B. Abstract Protocol Notation

(Note: I've adapated most of this from the extended EBNF in RFC 2616. Some of the descriptive text below is quoted directly from RFC 2616.)

A right-arrow character indicates the return types of a protocol operation.

instanceOf(<anyURI>)

Indicates a well-formed, and optionally valid, instance of an XML vocabulary identified by <URI>. For example, instanceOf(http://www.w3.org/1999/02/22-rdf-syntax-ns#) indicates a well-formed instance of RDF/XML. Representation types other than XML may be expressed in the same notation even if they do not define well-formedness or validity or define it differently than XML.

key: value

Two elements separated by a comma indicates a key-value pair.

A | B

Elements separated by a bar indicate alternatives.

{A, B, C}

Elements enclosed in curly braces and separated by a comma indicate a set of elements.

+(*A, 1*5B)

Elements, including optionals and repetitions, enclosed in +( and ), and separated by commas, indicate a bag—an unordered collection with duplicates.

(*A, 1*5B)

Elements, including optionals and repetitions, enclosed in parentheses, and separated by commas, indicate a list—an ordered collection with duplicates.

C(A, B)

A name followed by elements, including optionals, enclosed in parentheses and separted by commas indicate the arguments of an operation, C.

[A]

Elements enclosed in square brackets indicate optional elements.

*A

The asterisk character preceding an element indicates repetition. The full form is <n>*<m>element indicating at least <n> and at most <m> occurrences of element. Default values are 0 and no-upper-bound so that *(element) allows any number, including zero; 1*element requires at least one; and 1*2element allows one or two.

<n>(A)

Indicates <n> repetitions of A.

[A_B_C]

A string of bold upper case letters, separated by _, enclosed in square brackets indicates the abstract name of some HTTP query parameter.

C. Domain-specific Terms

Client, also Requester

From RFC 2616, "A program that establishes connections for the purpose of sending requests."

SPARQL Client

A program that establishes connections for the purpose of sending SPARQL abstract protocol requests.

Server, also Responder

From RFC 2616, "An application program that accepts connections in order to service requests by sending back responses."

SPARQL Server

A program that accepts connections in order to service SPARQL abstract protocol operations by returning the results of those operations and appropriate response types.

Origin Server

From RFC 2616, "The server on which a given resource resides or is to be created."

Operation Processor Service

There are at least two ways to conceptualize and implement a SPARQL server in a heterogenous environment like the Web. The first way is graph-centric: the resources exposed to SPARQL operations are RDF graphs. The second way is service-centric: the primary resource exposed is a service that receives requests for SPARQL operations and responds accordingly. In this document a service-centric SPARQL server is known as an Operation Processor Service.

Operation Point

A service or graph endpoint; i.e., a class of Web resource, identified by URI, that encompasses both SPARQL Operation Processor Services and RDF graphs. The SPARQL protocol conveys protocol operation requests, including queries, from SPARQL clients to Operation Points and returns the responses to clients.

RDF Query Language

A computer language for querying RDF graphs. For example, SPARQL Query Language for RDF, RDQL, and SeRQL are RDF query languages.

Query

A legal sentence in a particular RDF query language grammar.

RDF triple

From RDF Semantics, 6.1 RDF Triples, "An RDF triple contains three components: the subject, which is an RDF URi reference or a blank node; the predicate, which is an RDF URI reference; [and] the object, which is an RDF URI reference, a literal or a blank node."

Base RDF Triple, also Told RDF Triple

A base or told RDF triple is one that exists explicitly in an RDF graph or knowledge base. For example, in the RDF graph

@prefix triumph:  <http://triumph.example/schema/#> .
@prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

<http://triumph.example/part/0d92ie433>
    rdf:type    triumph:part ;
    rdfs:label  "Accelerator Cable MK3" ;
    triumph:part-number  "LCD 100-04BSPT" .

the RDF triple (http://triumph.example/part/0d92ie433, rdf:type, triumph:part) is a told or base triple.

Virtual RDF Triple, also Inferred RDF Triple

A virtual or inferred triple is one that does not exist explicitly in an RDF graph or knowledge base; it exists as a result of some inference or reasoning operation on the graph.

RDF graph

From RDF Semantics, 6.2 RDF Graph, "An RDF graph is a set of RDF triples. The set of nodes of an RDF graph is the set of subjects and objects of triples in the graph."

Abstract Protocol

A set of abstract protocol operations, basic types, and responses for conveying operation requests from clients to servers and for conveying operation results from servers to clients.

Concrete Protocol

A concrete implementation—concrete opereations, types, and responses—of the abstract protocol which may itself be realized by means of another, existing concrete protocol; for example, HTTP or SOAP.

Query Results

Some abstract protocol operations specify results that are to be returned by the server that executes those operations. Query and other operation results are to be distinguished from the response codes that the server may be required to return.

Query Result IMT

The Internet Media Type of a Query Result.

Operation Target Graph

An RDF graph against which a protocol operation, including a query, is to be executed.

4. Conformance Requirements

These conformance levels address which features of a concrete protocol are supported in implementations and are intended to allow implementations to easily describe their level of adherence to this specification in a machine-readable form. However, they must not be interpreted as constraining or requiring any implementation to make any RDF graph or query processor service publicly available or to support any protocol or query language features for any particular RDF graph or service.

A. Minimal Conformance

In order to be minimally conformant, an implementation must support all REQUIRED protocol operations and features.

B. Conformance

In order to be conformant, an implementation must support all REQUIRED and all CONFORMANT protocol operations features and may support zero or any number of OPTIONAL operations and features.

C. Maximal Conformance

In order to be maximally conformant, an implementation must support all REQUIRED, CONFORMANT, and OPTIONAL protocol operations and features.

5. Abstract Protocol

The SPARQL abstract protocol has three parts: types, operations, and responses.

A. Types

The abstract protocol uses the following types, which fall into three categories: W3C XML Schema types, which are relevant to all abstract protocol operations and borrowed from W3C XML Schema Datatypes; protocol types, which are relevant to abstract protocol operations; and query types, which are relevant to query operations.

W3C XML Schema Types

string

The string datatype represents character strings in XML. The value space of string is the set of finite-length sequences of characters (as defined in [XML 1.0 (Second Edition)]) that match the Char production from [XML 1.0 (Second Edition)]. A character is an atomic unit of communication; it is not further specified except to note that every character has a corresponding Universal Character Set code point, which is an integer.

boolean

The type boolean boolean has the value space required to support the mathematical concept of binary-valued logic: {true, false}.

anyURI

anyURI represents a Uniform Resource Identifier Reference (URI). An anyURI value can be absolute or relative, and may have an optional fragment identifier (i.e., it may be a URI Reference). This type should be used to specify the intention that the value fulfills the role of a URI as defined by RFC 2396, as amended by RFC 2732.

positiveInteger

positiveInteger is derived from nonNegativeInteger by setting the value of minInclusive to be 1. This results in the standard mathematical concept of the positive integer numbers. The value space of positiveInteger is the infinite set {1,2,...}.

Protocol Types

OperationProcessor

An OperationProcessor, which identifies a SPARQL processing service, is an anyURI to which a OperationContext is conveyed.

OperationTarget

An OperationTarget is an RDFGraph or an anyURI which identifies a RDF graph resource and against which a protocol operation is executed.

OperationTargetSet

A OperationTargetSet is a set of one or more distinct OperationTarget.

OperationPoint

An OperationPoint is any anyURI, identifying either an OperationProcessor or an OperationTarget, to which an RDF query, or other protocol operation, is conveyed.

Query Types

RDFGraph

RDFGraph is a canonically serialized RDF graph, that is, instanceOf(http://www.w3.org/1999/02/22-rdf-syntax-ns#). RDF/XML is the canonical way to serialize RDFGraph. There are other, semantically equivalent ways to serialize RDF graphs, and concrete protocols may allow for their use in addition to RDF/XML.

AllGraphTriples

Some abstract protocol operations require a succinct, RDF query language indpendent way to represent the selection of all RDF triples from an RDF graph. The SPARQL abstract protocol uses the asterisk, * (Unicode 002A), as the lexical representation of AllGraphTriples.

RDFGraphQuery

The SPARQL protocol is intended to convey RDF queries from many different RDF query languages. The type defined here, RDFGraphQuery, is a string which represents a legal query from any RDF query language. No grammar is given in this specification for RDFGraphQuery.

DistinctQueryResults

Some RDF query languages support the notion of distinct query results: duplicate query results are winnowed before being returned to the client. DistinctQueryResults is a key-value pair, distinct: boolean, where the value is a boolean: if true, distinct results must be returned to the client; if false, distinct results may not be returned to the client.

LimitQueryResults

Some RDF query languages support the notion of limiting the number of query results; LimitQueryResults is a key-value pair, limit: positiveInteger, where the value is a positiveInteger, which is the maximum number of query results that are to be returned to the client via the protocol.

StreamingQueryResults

Some RDF query languages support the notion of making all the elements of one solution to a query available to the requester before any elements of another solution are available to the client. StreamingQueryResults is a key-value pair, streaming: boolean, where the value is a boolean,: if true, streamed results must be returned to the client; if false, streaming results may not be returned to the client.

QueryBundle

A QueryBundle is a set—{RDFGraphQuery | AllGraphTriples | anyURI[, DistinctQueryResults, LimitQueryResults, StreamingQueryResults]}—comprised of either an RDFGraphQuery or an AllGraphTriples or an anyURI (which, when dereferenced, returns an RDFGraphQuery); an optional DistinctQueryResults; an optional LimitQueryResults; and an optional StreamingQueryResults.

BooleanQueryResult

Some RDF query languages, including SPARQL Query Language for RDF, allow for yes-no or boolean queries—called in this document BooleanQueryResult—the results of which is a boolean value.

VariableBindingSet
instanceOf(...)

A well-formed instance of @@, an XML vocabulary for exchanging variable binding set query result types. See ...

QueryResult

A QueryResult is either an RDFGraph, BooleanQueryResult, or VariableBindingSet.

B. Responses

The SPARQL Abstract Protocol defines three kinds of response: success, fault, and informational. Success responses indicate that the protocol operation was successfully executed; fault responses indicate that the protocol operation was not successfully executed; informational responses either provide additional information about an abstract protocol operation or describe specific conditions relevant to particular abstract protocol operations.

In response to abstract protocol operations, conforming implementations must return a response type indicating the status of the operation. Additionally, conforming implementations should return an RDF graph describing the response for machine processing. For some kinds of protocol operations, conforming implementations may return more than one response code.

The SPARQL abstract protocol defines the following responses.

Response Type Description
OK Success Operation completed successfully
GraphCreated Success Graph successfully created at anyURI
RequestAccepted Informational Operation was accepted but no further information provided.
RequestRefused Informational Operation was refused for an unspecified reason.
NoDeletionPerformed Informational Deletion operation request was refused.
MalformedRequest Fault Operation faulted because of some error in the request
Unauthorized Fault Operation request not authenticated
Forbidden Fault Operation faulted because it's forbidden.
NotFound Fault Operation faulted because target not found.
OperationPointError Fault Operation faulted because of unspecified error in OperationPoint
UnsupportedOperation Fault Operation faulted because it is unsupported for the identified graph.
Unavailable Fault Operation faulted because service or graph is temporarily unavaiable.
TemporarilyMoved Fault Service or graph has temporary moved to new location.
PermanentlyMoved Fault Resource or graph has permanently moved to new location.

C. Operations

The SPARQL Abstract Protocol is made up of seven orthogonal operations: query, getGraph, getOptions, makeGraph, dropGraph, addTriples, and deleteTriples.

Passing Arguments by Reference, Value, and Query

On the Web data can be passed from one entity to another in a variety of ways. A datum can be included in a request between entities. Or it can be treated as a first-class web resource, given a dereferenceable URI, and passed by reference—that is, a URI identifying the datum can be included in a request or response between entities, with the shared expectation that the URI will be dereferenced in order to retrieve a representation of the datum. It is desirable for a variety of reasons that the SPARQL Absract Protocol be agnostic as to the various ways in which SPARQL concrete protocol designs may pass data between entities.

In the context of the Web, passing data by reference means passing data—whether queries, query targets, other operation targets, or other data—by way of passing a URI that, when dereferenced, returns a representation of that data. For example, consider the utility of authoritative sets of rules for processing subsets of OWL or RDFS. One way to share such rulesets on the Web is by giving them authoritative, or at least conventionally well-known, URIs, so that they can be retrieved when needed. We anticipate the same utility for stable URIs identifying authoritative or canonical RDF queries, including SPARQL Query Language for RDF queries. And the same considerations that apply to RDF queries are likely to apply to canonical or authoritative RDF graphs.

Alternately, in some situations, it's easier or more elegant to pass data by value, which means here passing data in requests or responses between entities by directly including that data in those requests or responses in some realized representational form. Thus, in some of the protocol operation definitions in this section, it is permissible to include a string that is a valid RDFGraphQuery in some RDF query language grammar. And in other operations it is permissible to include an RDFGraph with or against which some operation is to be performed.

Finally, in yet other situations, it may not be practical either to pass a datum by value, perhaps because the datum is not yet known, or to pass the datum by reference, perhaps because no such URI exists. In some of these situations, it may make good sense to pass the data by query or by "computed value". Passing by query means passing arguments in which the literal representational form is a query that is to be executed against a graph, the QueryResults of which are used in some protocol operation.

The definitions of abstract operations, types, responses presented in this document are such as to constrain SPARQL concrete protocols as little as possible with regard to these ways of passing data on the Web.

Implicit Arguments

All of the abstract protocol operations defined here, with the exception of makeGraph, are equally well conveyed to an RDF graph as to an operation processing service. This specification, therefore, aims to be agnostic as to which kind of entity these operations are conveyed. But in the case where an operation is conveyed to an RDF graph, that RDF graph must be considered the implicit OperationTarget against which the operation is to be executed. Thus, an OperationPoint is defined as an anyURI that identifies either an OperationTarget or an OperationProcessor. If it identifies the latter, then the request must also include either an OperationTarget or an OperationTargetSet. If it identifies the former, then the request may include an OperationTargetSet, and conformant implementations must treat the OperationPoint as the target against which an operation is to be executed. The getOptions operation may be used to determine the type of an OperationPoint.

1. query

query(QueryBundle, OperationPoint[, (OperationTarget | OperationTargetSet)]) → {QueryResult, Response}

Identifier: tag:monkeyfist.com,2004-10-13:/sparql-p/abstract/operation/query

Conceptually, the arguments to the query operation are threefold: (1) the query; (2) an entity responsible for handling the query, in some unspecified manner; and (3) the target(s) against which the query is to be executed. The QueryBundle contains or points to, via URI, the query itself, as well as some information about how query results are to be handled: whether some upper bound on the number of returned results is required, and whether results should be distinct. The OperationPoint identifies the entity to which the query is conveyed. The optional OperationTarget or OperationTargetSet identifies the RDF graph or graphs against which the query is to be executed.

The query operation must convey a query to an OperationPoint and must return the results of the query. The results of the query operation must include one of these response types: OK, MalformedRequest, Unauthorized, Forbidden, NotFound, OperationPointError, UnsupportedOperation, Unavailable, TemporarilyMoved, or PermanentlyMoved.

For example, query({*, distinct: true}, http://example/1.rdf) should convey to http://example/1.rdf the AllGraphTriples query to be executed against http://example/1.rdf. However, query({"select ?a where (?a, rdf:type, foaf:Person)", limit: 5}, http://example2/qsp, {http://example/3.rdf, 2.rdf, http://example2/3.rdf}) does not rely on an implicit identification of the target of the operation; it conveys the query to the OperationPoint http://example2/qsp, to be executed against the target set {http://example/3.rdf, 2.rdf, http://example2/3.rdf}, and it requests that a maximum of 5 query results be returned.

query is a REQUIRED protocol operation.

2. getGraph

getGraph(OperationPoint[, (OperationTarget | OperationTargetSet)]) → (1*RDFGraph, 1*Response)

Identifier: tag:monkeyfist.com,2004-10-13:/sparql-p/abstract/operation/getGraph

getGraph is a simple operation, essentially requesting a representation of one, or distinct representations of more than one, RDFGraph(s), identified by one or more anyURIs, from an OperationPoint. Thus, getGraph returns the serialized RDFGraph identified by OperationTarget or all of the separately serialized RDFGraphs identifed by OperationTargetSet. SPARQL concrete protocols should specify expected behavior in the case where one or more members of the OperationTargetSet are unavailable, but one or more are available, for retrieval. The results of the getGraph operation must include one or more of these response types: OK, MalformedRequest, Unauthorized, Forbidden, NotFound, OperationPointError, UnsupportedOperation, Unavailable, TemporarilyMoved, or PermanentlyMoved.

For example, getGraph(http://example/qsp, {http://example/1.rdf, http://example/2.rdf/, 3.rdf}) is a request, conveyed to http://example/qsp, for three RDFGraphs: http://example/1.rdf, http://example/2.rdf, and 3.rdf. Likewise, getGraph(http://example/3.rdf) is a request, conveyed to http://example/3.rdf for the RDFGraph identified by http://example/3.rdf.

getGraph is a REQUIRED protocol operation.

3. getOptions

getOptions(OperationPoint[, (OperationTarget | OperationTargetSet)]) → (1*RDFGraph, 1*Response)

Identifier: tag:monkeyfist.com,2004-10-13:/sparql-p/abstract/operation/getOptions

The getOptions operation returns an RDFGraph that describes the protocol and query language options for a particular RDFGraph or for OperationProcessor. The results of the getOptions operation must include one or more of these response types: OK, MalformedRequest, Unauthorized, Forbidden, NotFound, OperationPointError, UnsupportedOperation, Unavailable, TemporarilyMoved, or PermanentlyMoved.

For example, getOptions(http://example/qsp) returns—on the assumption that http://example/qsp identifies an OperationProcessor—an RDFGraph describing the protocol and query language options, as well as the available QueryTargets. Likewise, getOptions(http://example/qsp, 2.rdf) returns an RDFGraph describing the protocol and query language options that may be invoked with 2.rdf as an OperationTarget. Finally, getOptions(http://example/3.rdf) returns an RDFGraph describing the protocol and query language options that may be invoked with http://example/3.rdf as an OperationPoint or OperationTarget.

See 6. Advertisement and Discovery for a detailed discussion of expectations and conventions related to the protocol and query language description format.

getOptions is a CONFORMANT protocol operation.

4. makeGraph

makeGraph(OperationProcessor, RDFGraph | anyURI | QueryBundle) → (Response)

Identifier: tag:monkeyfist.com,2004-10-13:/sparql-p/abstract/operation/makeGraph

makeGraph transfers an RDFGraph from the requester to the responder, with the expectation that the RDFGraph will be available as a OperationTarget for future protocol operations. The results of the makeGraph operation must include one or more of these response types: GraphCreated, RequestAccepted, MalformedRequest, Unauthorized, Forbidden, NotFound, OperationPointError, UnsupportedOperation, Unavailable, TemporarilyMoved, or PermanentlyMoved.

For example, makeGraph(http://example/qsp, instanceOf(instanceOf(http://www.w3.org/1999/02/22-rdf-syntax-ns#))) requests that http://example/qsp create a new RDFGraph as represented by the included instance of an RDF graph. Likewise, makeGraph(http://example/qsp, http://site/my.rdf) requests that http://example/qsp create a new RDF graph identical to the one identified by http://site.my.rdf. Finally, makeGraph(http://example/qsp, {"select ?a where (?a, rdf:type, foaf:Person)", limit: 5, distinct:true}) requests that http://example/qsp create a new RDF graph identical to the one that results from computing the query...

A conforming SPARQL server implementation which supports the makeGraph cannot be further obligated to create any arbitrary RDF graph, retrieve any arbitrary graph for creation, or otherwise commit itself to arbitrary operations on a created graph in the future. In these or similar cases, the responder should return, in preference to a more generic response, such as Unavailable or OperationPointError, the more specific RequestRejected response and may include both a human-readable and RDF description of the reasons for rejecting the request, particularly if the request could be accepted in the future.

makeGraph is an OPTIONAL protocol operation.

5. dropGraph

dropGraph(OperationPoint[, (OperationTarget | OperationTargetSet)]) → (Response)

Identifier: tag:monkeyfist.com,2004-10-13:/sparql-p/abstract/operation/dropGraph

One of the implications of the opacity of URIs is that we cannot know whether a URI identifies an RDF graph that is implemented as a file in a filesystem, as a high-level programming language script, or as a database query. Accordingly, the semantics of the abstract protocol operation dropGraph are necessarily limited to removing the identified RDF graph from among the set of graphs to which a conforming implementation will apply protocol operations. Whether there are other side effects of the operation—actual file deletions or database changes—is implementation-specific. The results of the dropGraph operation must include one of these response types: OK, MalformedRequest, Unauthorized, Forbidden, NotFound, OperationPointError, UnsupportedOperation, Unavailable, TemporarilyMoved, or PermanentlyMoved.

For example, dropGraph(http://example/3.rdf) removes http://example/3.rdf from the set of RDF graphs that can be the target of protocol operations. Likewise, dropGraph(http://example/qsp, http://example/4.rdf) removes http://example/4.rdf from the set.

dropGraph is an OPTIONAL protocol operation.

6. addTriples

addTriples(OperationPoint, RDFGraph[, (OperationTarget | OperationTargetSet)]) → (1*Response)

Identifier: tag:monkeyfist.com,2004-10-13:/sparql-p/abstract/operation/addTriples

The addTriples operation adds one or more RDFTriples, serialized in an RDFGraph, to one or more existing RDFGraphs. This document takes no position on issues relating to concurrent access, transactions, resource locking or contention. The results of the addTriples operation must include one of these response types: OK, MalformedRequest, Unauthorized, Forbidden, NotFound, OperationPointError, UnsupportedOperation, Unavailable, TemporarilyMoved, or PermanentlyMoved.

For example, addTriples(http://example/qsp, instanceOf(http://www.w3.org/1999/02/22-rdf-syntax-ns), http://example/3.rdf) adds the triples serialized as RDF/XML to the RDFGraph identified by http://example/3.rdf>.

addTriples is an OPTIONAL protocol operation.

7. deleteTriples

deleteTriples(OperationPoint, (RDFGraphQuery | AllGraphTriples)[, (OperationTarget | OperationTargetSet)]) → (1*Response)

Identifier: tag:monkeyfist.com,2004-10-13:/sparql-p/abstract/operation/deleteTriples

The deleteTriples operation causes one or more triples to be removed from the RDF graph(s) identified by the OperationTarget or OperationTargetSet. Deleting triples from RDF graphs may be a a complex operation, especially when some form of inferencing may be performed. In some cases a query may identify a triple that is inferred or virtual on the basis of one or more explicitly asserted or told triples. In order to remove a virtual triple from an RDF graph, it may be necessary to delete one or more told triples, but which ones?

Thus, the deleteTriples operation defined in this specification applies to told triples only; deleteTriples may delete explicitly asserted triples only. If a triple T is deleted as a result of deleteTriples, but is still entailed by the RDF graph, then it will still exist in the RDF graph after the deleteTriples operation was invoked.

There are six possible cases when the deleteTriples(T) operation is invoked:

  1. T is a told triple.
  2. T is an inferred triple.
  3. T is both an inferred and a told triple.
  4. T is a set of told triples.
  5. T is a set of inferred triples.
  6. T is a set of triples, some of which are told, some of which are inferred, others of which are both told and inferred.

In cases (1) or (4), if one or more triples are removed from the graph(s), OK must be returned. In cases (2) and (5), if no triple or triples are removed from the graph(s), the NoDeletionPerformed response must be returned. In case (3), if a triple is removed from the graph(s), then the OK response must be returned, but there is no guarantee that other triples have not also been deleted. In case (3), if a triple is not removed from the graph(s), then the NoDeletionPerformed response must be returned. In case (6), if any triple or triples are removed from the graph(s), the OK response must be returned; if no triple or triples are removed, the NoDeletionPerformed code must be returned.

The results of the deleteTriples operation must include one of these response types: OK, MalformedRequest, Unauthorized, Forbidden, NotFound, OperationPointError, UnsupportedOperation, Unavailable, TemporarilyMoved, PermanentlyMoved, RequestRefused, or NoDeletionPerformed.

deleteTriples is an OPTIONAL protocol operation.

6. Advertisement and Discovery

Service and Resource Advertisement

Since the SPARQL abstract protocol is designed to convey RDF queries between software entities acting as requesters and responders, and since RDF is a key element of the Semantic Web, it is reasonable to devise a set of strategies for accomplishing machine-readable advertisement and discovery of SPARQL services.

Ideally the means of advertising the features of a particular SPARQL implementation is publishing an RDF graph, which describes that implementation, on the Web. Software entities required to interact with a particular instance of a SPARQL server, for example, may dereference a URI in order to retrieve a representation of an advertisement resource. That representation of an RDF graph would contain assertions made by using well-known predicates that together describe the protocol and query language features, as well as implementation details, of a SPARQL service.

There are at least three ways through which an RDF vocabulary—a set of predicates, together with a way of naming resources or coining URIs—for describing SPARQL implementations might be derived:

  1. adapt an existing vocabulary;
  2. create a new vocabulary; or
  3. await the gradual evolution of a vocabulary.

Even in the case where a SPARQL deployment is not realized by using web services technologies like SOAP and WSDL, the relevant pieces of information that belong in an advertisement vocabulary are mostly the pieces of information captured by the W3C's Web Services Description Language (WSDL) vocabulary. In other words, either (2) or (3) will inevitably recreate a significant subset of the work the creators of WSDL have already accomplished. Given the benefits of common vocabulary usage, it makes sense to pursue (1), namely, creating some kind of adoption strategy that uses WSDL to describe and thus advertise SPARQL implementations and deployments thereof.

WSDL 2.0 has as one of its goals the creation of an RDF mapping, by means of which, presumably, any valid instance of WSDL 2.0 can be converted into an RDF graph. Such a mapping would mean that SPARQL users could employ WSDL tools to describe SPARQL servers, clients, and deployments thereof. It would also mean that such software entities would ultimately be dereferencing, retrieving, and interacting with RDF graphs, the predicates of which would be ultimately traceable to the service description work done by the creators of WSDL.

But what pieces of information are we interested in advertising in this way?

  1. the supported protocol features and operations for a particular SPARQL implementation generally
  2. the supported protocol features and operations for a particular SPARQL deployment specifically
  3. the set of RDF graphs to which protocol operations may be conveyed
  4. supported protocol features and operations for specific RDF graphs
  5. operation calling and data passing conventions, parameter names, supported concrete protocol features
  6. supported RDF query languages
  7. available SPARQL Query Language for RDF features

Resource and Service Discovery

The abstract protocol opereation, getOptions, is the means of retrieving a machine-readable description of a service or resource advertisement.

But how do we discover these descriptions arbitrarily?

7. SPARQL Concrete HTTP Binding

[[One aspect of SPARQL protocol deployment that deserves special mention here is the issue of URI construction. In general there are three options for specifying how URIs may be constructed programmatically: URIs and parts of URIs, including query parameter names, can be hardcoded in a specification; a specification can describe how URIs and parts of URI, including query parameter names, can be dynamically discovered—for example, by dereferencing a known URI that describes, say, the names of query parameters; or, last, the specification can describe a generative naming scheme for creating URIs and parts of URIs.

The simplest and most inflexible of these three ways is to hardcode URIs and their parts into a specification. It is simple in the sense that, once it's completed, implementers simply use the hardcoded values in the specification. But it is the most inflexible because implementers can only use the values hardcoded in the specification, which may prove onerous or confusing or costly in some cases.

For example, consider the names of query parameters. In an environment as multilingual as the Web, where great care is taken about i18n issues, the question of whether to hardcode URI query parameter names is a very difficult one. Why should English be the natural language of choice? And how do we justify that choice when Unicode and IRIs suggest linguistic flexibility and cultural sensitivity?

Further, one of the principles of Web Architectures is URI ownership, which suggests that specifications ought to be sensitive to the fact that URI owners control the coinage of new URis within their namespaces. That sensitivity suggests a prima facie case against hardcoding URIs and URI parts in a specification, since such hardcoding may unnecessarily restrict the freedom of URI owners to exercise URI ownership.

While we cannot solve these issues today, we can avoid locking ourselves and implementers into an anti-solution, by choosing either a generative or discovery scheme, rather than a hardcoding one.]]

SPARQL HTTP Protocol Types

Mapping SPARQL Abstract Response Types to HTTP Status Codes

SPARQL Abstract Response Type HTTP Response Code
OK 200 OK
GraphCreated 201 Created
OperationRequestAccepted 202 Accepted
PermanentlyMoved 301 Moved Permanently
TemporarilyMoved 307 Temporary Redirect
MalformedRequest, MalformedQuery 400 Bad Request
Unauthorized 401 Unauthorized
Forbidden 403 Forbidden
NotFound 404 Not Found
NoDeletionPerformed, RequestRefused 409 Conflict
OperationPointError 500 Internal Server Error
UnsupportedOperation 501 Not Implemented
Unavailable 503 Service Unavailable

Operations

@@ need discussion of each one, but examples work for now to make the point

@@ need to add more examples: addTriples by query; non-sparql query example; conditional get; cache-control; authentication; faults; response bodies in RDF; Allow, Expect, Accept-Range

@@ sort out the return types: xml var bindings, rdf subgraphs, var bindings in rdf, booleans

@@ show the alternate query form for queries that are too long to be conveyed via GET and query parameters...

1. query

1.1 query: One query against one RDF graph

GET /qps?[GRAPH_ID]=http%3A%2F%2Fmy.example%2F3.rdf&[QUERY]=SELECT+%3Fa%2C+%3Fb%2C+%3Fc+WHERE+%28%3Fa%2C+%3Fb%2C+%3Fc%29 HTTP/1.1
User-Agent: my-sparql-client/0.0
Sparql-Distinct: true
Sparql-Stream: false
Sparql-Limit: 10
Host: my.example
200 OK HTTP/1.1
Server: my-sparql-server/0.0
Content-Type: application/xml

<?xml version="1.0" encoding="UTF-8"?>

<results xmlns="http://www.w3.org/sw/2001/DataAccess/result1#">
  <result>
    <a uri="http://work.example.org/alice/"/>
    <b uri="http://work.example.org/#name"/>
    <c>Alice</c>
  </result>
  <result> 
    <a uri="http://work.example.org/bob/"/>
    <b uri="http://work.example.org/#name"/>
    <c xml:lang="en">Bob</c>
  </result>
</results>

1.2 query: One query, passed by reference, against one RDF graph

GET /qps?[GRAPH_ID]=http%3A%2F%2Fmy.example%2F3.rdf&[QUERY_ID]=http%3%2F%2Fmy.example%2Fquery.spql HTTP/1.1
User-Agent: my-sparql-client/0.0
Sparql-Distinct: true
Sparql-Stream: false
Sparql-Limit: 10
Host: my.example
200 OK HTTP/1.1
Server: my-sparql-server/0.0
Content-Type: application/rdf+xml

<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF 
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" 
    xmlns:iswc="http://annotation.semanticweb.org/2004/iswc#" 
    xml:base="http://www.mindswap.org/2004/iswc">
  <iswc:InProceedings rdf:ID="server-side-xptr-paper">
    <rdfs:seeAlso rdf:resource="iswc.html"/>
    <iswc:title>A Semantic Web Resource Protocol: XPointer and HTTP</iswc:title>
    <iswc:author rdf:resource="#bijan"/>
    <iswc:author rdf:resource="http://clark.dallas.tx.us/kendall/foaf.rdf"/>
    <iswc:author rdf:resource="#bryan"/>
    <iswc:conference rdf:resource="#ISWC2004"/>
    <iswc:year>2004</iswc:year>
    <iswc:topic rdf:resource="http://annotation.semanticweb.org/2004/iswc#Semantic_Web_Middleware"/>
  </iswc:InProceedings>
</rdf:RDF>

1.3 query: One query against multiple RDF Graphs

GET /qps?[GRAPH_ID]=2.rdf&[GRAPH_ID]=4.rdf&[GRAPH_ID]=http%3A%2F%2Ffoaf.example%2Ffoaf%3fid=50&[QUERY]=SELECT+%2A HTTP/1.1
User-Agent: my-sparql-client/0.0
Sparql-Distinct: true
Sparql-Stream: false
Sparql-Limit: 10
Host: my.example
200 OK HTTP/1.1
Server: my-sparql-server/0.0
Content-Type: multipart/mime

1.4 query: Multiple queries against one RDF Graph

GET /3.rdf?[QUERY]=SELECT+%2A&[QUERY]=...ASK+%28%3Fx+foaf%3Ambox_sha1sum+%22ABCD1234%22%29 HTTP/1.1
User-Agent: my-sparql-client/0.0
Sparql-Distinct: true
Sparql-Stream: false
Sparql-Limit: 10
Host: my.example
200 OK HTTP/1.1
Server: my-sparql-server/0.0
Content-Type: multipart/mime

2. getGraph

2.1 getGraph: Retrieve graph with content negotiation for RDF/XML

GET /qps?[GRAPH_ID]=1.rdf HTTP/1.1
Accept: application/rdf+xml;q=0.9,text/n3;q=0.2
Accept-Encoding: gzip,deflate,compress;q=0.9
Accept-Charset: utf-8 
User-Agent: my-sparql-client/0.0
Sparql: distinct,stream,limit=10
Host: my.example
200 OK HTTP/1.1
Server: my-sparql-server/0.0
Content-Type: application/rdf+xml

<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF>...</rdf:RDF>

2.2 getGraph Retrieve RDF graph with content negotiation for N3

GET /3.rdf HTTP/1.1
Accept: text/n3
Accept-Encoding: gzip,deflate,compress;q=0.9
Accept-Chareset: utf-8
User-Agent: my-sparql-client/0.0
Host: my.example
200 OK HTTP/1.1
Content-Type: text/n3

@prefix foaf:   .

[]
     foaf:name   "Johnny Lee Outlaw" ;
     foaf:mbox   <mailto:jlow@example.com> .

2.3 getGraph: Retrieve multiple RDF graphs

GET /qps?[GRAPH_ID]=2.rdf&[GRAPH_ID]=4.rdf HTTP/1.1
User-Agent: my-sparql-client/0.0
Host: my.example
200 OK HTTP/1.1
Content-Type: multipart/related
...

3. getOptions

3.1 getOptions: Retrieve options for a SPARQL implementation

OPTIONS /qps HTTP/1.1
Accept: application/rdf+xml,text/n3,application/x-turtle
Accept-Encoding: gzip,deflate,compress;q=0.9
Accept-Charset: utf-8
User-Agent: my-sparql-server/0.0
Host: my.example
200 OK HTTP/1.1
Content-Type: application/x-turtle
User-Agent: bob's-sparql-server/0.1

...

3.2 getOptions: Retrieve options for multiple RDF graphs

OPTIONS /qps?[GRAPH_ID]=3.rdf&[GRAPH_ID]=5.rdf HTTP/1.1
Accept: application/rdf+xml,application/x-turtle,text/n3
Accept-Encoding: gzip,deflate,compress;q=0.9
Accept-Charset: utf-8
User-Agent: my-sparql-client/0.0
Host: my.example
200 OK HTTP/1.1
Content-Type: multipart/related
User-Agent: bob's-sparql-server/0.1

...

3.3 getOptions: Retrieve options for an RDF graph

OPTIONS /3.rdf HTTP/1.1
Accept: application/rdf+xml,application/x-turtle,text/n3
Accept-Encoding: gzip,deflate,compress;q=0.9
Accept-Charset: utf-8
User-Agent: my-sparql-client/0.0
Host: my.example
200 OK HTTP/1.1
Content-Type: application/rdf+xml
User-Agent: bob's-sparql-server/0.1

...

3.4 getOptions: Retrieve options for an unsupported RDF graph

OPTIONS /qps?[GRAPH_ID]=http%3A%2F%2Fmy.site.example%2Ffoaf.rdf HTTP/1.1
Accept: application/rdf+xml,application/x-turtle,text/n3
Accept-Encoding: gzip,deflate,compress;q=0.9
Accept-Charset: utf-8
User-Agent: my-sparql-client/0.0
Host: my.example
403 Forbidden HTTP/1.1
Content-Type: application/rdf+xml
User-Agent: bob's-sparql-server/0.1

<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dawg="http://dawg/protocol/#">
  <dawg:Description rdf:nodeID="gensym_123abcd">
    <rdf:type rdf:resource="http://dawg/protocol/#UnsupportedOperation">
    <dawg:abstract-operation rdf:resource="tag:monkeyfist.com,2004-10-13:/sparql-p/abstract/operation/getOptions">
    <dawg:against rdf:resource="http://my.site.example/foaf.rdf"/>
  </dawg:Description>
</rdf:RDF>

3.5 getOptions: Discover Advertisement URI for a SPARQL Implementation

OPTIONS * HTTP/1.1
Accept: application/rdf+xml
Host: my.example
200 OK HTTP/1.1
Content-Type: application/rdf+xml

<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
   xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <rdf:Description rdf:about="http://my.example/qps">
    <rdf:type rdf:resource="http://dawg/protocol/#server"/>
  </rdf:Description>
</rdf:RDF>

4. makeGraph

4.1 makeGraph: Make an RDF graph passed by reference

POST /qps?[SRC_GRAPH_ID]=http%3F%2F%2F/foo.rdf HTTP/1.1
Content-Type: text/n3
Host: my.example
201 Created HTTP/1.1
Location: http://my.example/6.rdf

4.2 makeGraph: Make an RDF graph passed by value

POST /qps HTTP/1.1
Content-Type: application/rdf+xml; charset=utf-8
Host: my.example

<xml version="1.0"?>

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
    xmlns:foaf="http://xmlns.com/foaf/0.1/">
<foaf:Person rdf:ID="kendall">
  <foaf:name>Kendall Grant Clark</foaf:name>
  <foaf:mbox rdf:resource="mailto:kendall@monkeyfist.com"/>
  <foaf:mbox rdf:resource="mailto:kclark@ntlug.org"/>
  <foaf:nick>k</foaf:nick>
  <foaf:nick>kendallc</foaf:nick>
  <foaf:nick>kclark</foaf:nick>
</foaf:Person>
</rdf:RDF>
201 Created HTTP/1.1
Location: http://my.example/5.rdf

4.4 makeGraph: Make RDF graph with fault

POST /qps HTTP/1.1
Content-type: application/rdf+xml
Host: my.example

...
403 Forbidden  HTTP/1.1
Content-Type: application/rdf+xml; charset=utf-8

...

5. dropGraph

5.1 dropGraph: Successfully drop RDF graph, with status response message

DELETE /qps?[GRAPH_ID]=3.rdf HTTP/1.1
Host: my.example
200 OK HTTP/1.1
Content-Type: application/rdf+xml; charset="utf-8"


<rdf:RDF>...</rdf:RDF>

5.2 dropGraph: Successfully drop RDF graph, with informational response type

DELETE /3.rdf HTTP/1.1
Host: my.example
202 Accepted HTTP/1.1

5.3 dropGraph: Successfully drop RDF graph, with no status message

DELETE /qps?[GRAPH_ID]=5.rdf HTTP/1.1
Host: my.example
204 No Content HTTP/1.1

5.3 dropGraph: Unsuccessfully drop RDF graph

DELETE /4.rdf HTTP/1.1
Host: my.example
403 Forbidden HTTP/1.1

6. addTriples

Note: PUT implies a concatenative, not a replacement semantics here. [@@ What if resource doesn't exist?]]

6.1 addTriples: Adding RDF triples, passed by value, with new RDF graph returned in body

PUT /qps?[GRAPH_ID]=4.rdf
Content-Type: text/n3
Host: my.example

@prefix prf:     .
@prefix xsd:     .
[]
    prf:BitsPerPixel "8"^^xsd:int ;
    prf:ColorCapable "true"^^xsd:boolean ;
    prf:CPU "Arm 7" ;
    prf:ImageCapable "true"^^xsd:boolean ;
    prf:ScreenSize "101x80" ;
    prf:SoundOutputCapable "false"^^xsd:boolean ;
    prf:Vendor "Panasonic" .
200 OK HTTP/1.1
Content-Type: application/rdf+xml

<xml version="1.0" encoding="utf-8">
...

6.2 addTriples: Adding RDF triples, passed by value, with no response body

PUT /qps?[GRAPH_ID]=5.rdf HTTP/1.1
Host: my.example
Content-Type: application/rdf+xml

<?xml encoding="utf-8" version="1.0"?>

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
   xmlns:foaf="http://xmlns.com/foaf/0.1/">

<foaf:Person rdf:nodeID="eddtoo">
  <foaf:myersBriggs>ENFJ</foaf:myersBriggs>
  <foaf:aimChatID>EddDumbill</foaf:aimChatID>
  <foaf:homepage rdf:resource="http://heddley.com/edd/" />
  <foaf:mbox rdf:resource="mailto:edd@xml.com"/>
</foaf:Person>

</rdf:RDF>
204 No Content HTTP/1.1

6.3 addTriples: Adding RDF triples passed by reference

PUT /qps?[GRAPH_ID]=http%3A%2F%2Fyr.site.example%2Ffoo.ttl&[SRC_GRAPH_ID]=5.rdf
Host: my.example
Accept: application/rdf+xml; charset=utf-8
200 OK HTTP/1.1
Content-Type: application/rdf+xml
Content-Length: ...

<?xml version="1.0" encoding="utf-8">
...

6.4 addTriples: Adding RDF triples from multiple sources, passed by reference

PUT /qps?[SRC_GRAPH_ID]=http%3A%2F%2Fyr.site.example%2Ffoo.ttl&[SRC_GRAPH_ID]=4.rdf&[GRAPH_ID]=5.rdf
Host: my.example
Accept: application/rdf+xml; charset=utf-8
200 OK HTTP/1.1
Content-Type: application/rdf+xml
Content-Length: ...

<?xml version="1.0" encoding="utf-8">
...

6.5 addTriples: Adding RDF triples from multiple sources, passed by reference, to multiple RDF graphs

PUT /qps?[SRC_GRAPH_ID]=http%3A%2F%2Fyr.site.example%2Ffoo.ttl&[SRC_GRAPH_ID]=4.rdf&[GRAPH_ID]=6.rdf&[GRAPH_ID]=5.rdf
Host: my.example
Accept: application/rdf+xml; charset=utf-8
200 OK HTTP/1.1
Content-Type: multipart/related

...

7. deleteTriples

@@ FINISH ME

Passing by query:

DELETE /qsp?[GRAPH_ID]=...&[QUERY]=... HTTP/1.1
Host: my.example
204 No Content HTTP/1.1
DELETE /3.rdf?[QUERY]=...HTTP/1.1
host: my.example
200 OK HTTP/1.1

...

Passing by reference:

DELETE /qsp?[GRAPH_ID]=...&[SRC_GRAPH_ID]=... HTTP/1.1
host: my.example
...
DELETE /3.rdf HTTP/1.1
Content-Type: application/rdf+xml
host: my.example

<xml version="1.0" encoding="utf-8">
...
...

8. References

Joseki, DIG, AtomAPI, Annotea Protocol, REST, SS XPtr stuff, HTTP 1.1 spec, TAG URIs, WebArch

9. Acknowledgments

My thanks to members of DAWG, especially Bryan Thompson, Andy Seaborne, and Eric Prud'hommeaux, as well as to my UMD colleagues Bijan Parisa, Jim Hendler, Ron Alford, and the members of the Mindlab Semantic Web Undergraduate Social—all of whom helped make this document possible.