This document describes AllegroGraph's SPARQL Protocol client. This module allows you to run queries against SPARQL servers (termed "endpoints") via HTTP. AllegroGraph seamlessly translates the protocol responses into native results, so you can query remote triple stores without changing your code.
Exported from the sparql.client
package is run-sparql-remote. This gives you access to remote SPARQL endpoints (for SELECT
and ASK
queries) just as run-sparql
lets you query local triple stores. Here's an example, querying the DBpedia.org SPARQL endpoint:
sparql.client(2): (run-sparql-remote "http://wikipedia.org/sparql" "
PREFIX wikipedia: <http://wikipedia.org/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT ?person {
?person wikipedia:birthplace <http://wikipedia.org/resource/Berlin> .
}
LIMIT 10" :results-format :alists)
(((?person . !<http://wikipedia.org/resource/Alexander_Grothendieck>))
((?person
. !<http://wikipedia.org/resource/Frederick_William%2C_Elector_of_Brandenburg>))
((?person . !<http://wikipedia.org/resource/Herbert_Marcuse>))
((?person . !<http://wikipedia.org/resource/Konrad_Zuse>))
((?person . !<http://wikipedia.org/resource/Leni_Riefenstahl>))
((?person . !<http://wikipedia.org/resource/Nastassja_Kinski>))
((?person
. !<http://wikipedia.org/resource/Otto_Wilhelm_Hermann_von_Abich>))
((?person . !<http://wikipedia.org/resource/Walter_Gropius>))
((?person . !<http://wikipedia.org/resource/Erich_H%C3%BCckel>))
((?person . !<http://wikipedia.org/resource/Hans_Richter_%28artist%29>)))
:select
(?person)
Note that you don't need to have a database open to issue a remote query:
sparql.client(3): *db*
nil
All of the SPARQL results formats that are natively supported for local AllegroGraph ASK
and SELECT
queries are supported for remote queries, and the values returned by run-sparql-remote are compatible with run-sparql
. If you don't rely on any extended features, you can seamlessly switch between local and remote queries. You can obtain a list of possible results-formats by calling get-allowed-remote-results-formats.
Because of the similarity between the local and remote query functions, you can easily hide the distinction if the performance difference is of no concern:
(defun query-wherever (uri &rest args)
(if uri
(apply #'sparql.client:run-sparql-remote uri args)
(apply #'sparql:run-sparql args)))
(defun get-people (&optional uri)
"Return a list of people in the store.
If a URI is provided, the remote store is used instead."
(let ((q- "
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?person {
?person a foaf:Person .
}"))
(mapcar #'car
(query-wherever uri q :results-format :lists))))
Be aware
There are a few points to bear in mind when using remote queries.
- Remote queries have more overhead than local queries. You must include HTTP request and response times, parsing the response, and applying results formats in your estimates. For illustration, here is the time profile for the query at the start of this document:
; cpu time (non-gc) 0 msec user, 0 msec system ; cpu time (gc) 0 msec user, 0 msec system ; cpu time (total) 0 msec user, 0 msec system ; real time 710 msec
- Remote queries raise a wider variety of errors than local queries. For example:
;; Try a URL that doesn't exist. sparql.client(6): (run-sparql-remote "http://ireallydonotexist.net/sparql" "SELECT * {}" :results-format :count) Error: Unknown hostname: "ireallydonotexist.net" [condition type: simple-error] ;; Try a URL that does exist, but isn't a SPARQL endpoint. sparql.client(7): (run-sparql-remote "http://example.com" "SELECT * {}" :results-format :count) Error: Invalid MIME type returned for remote query: text/html; charset=UTF-8 [condition type: sparql-remote-incorrect-mime-type-error]
Remote endpoints might interpret the SPARQL standard differently, support different extensions, or otherwise be incompatible with AllegroGraph. AllegroGraph usually has to parse your query before dispatching it, and it certainly has to parse the response: this means that, in general, remote queries are restricted to standard SPARQL features, and cannot extend the SPARQL XML results format. This restriction does not apply to named extension functions, or legal extensions of
FILTER
semantics.AllegroGraph doesn't currently translate from s-expressions into text: use the standard SPARQL text format ("
SELECT ...
") for your queries. Most users will not be affected by this.Local queries (in most circumstances) return UPIs: internal representations of values in the triple store. Remote queries have no dependency on a local store, and return
future-parts
: in-memory abstractions of RDF values. You should be careful not to use UPI-specific functions on remote values. Most users will not be affected by this.
— AllegroGraph spends an immeasurably small amount of time making and parsing the request, but it spends about 700ms just waiting for the response to arrive.
These errors might occur prior to the request, whilst parsing your query for dispatch; during HTTP transport (such as the hostname error above); or whilst parsing the response (as in the MIME type error).
API reference
Run a SPARQL query against a remote endpoint, locally serializing the results to 'output-stream' in the appropriate format (as with run-sparql
).
The value of the uri
argument is provided to net.aserve.client:do-http-request; it can be a string or a net.uri:uri
.
If output-stream
is null, and the results format is one that generates textual output, then the serialized output is returned as a string.
Other arguments (such as :from
and :from-named
, and arguments to net.aserve.client:do-http-request
) are passed to run-sparql-remote-with-results-functions
.
You can use this opportunity to provide :method :post
to encode large queries in the request body.
If :function
or :passthrough-function
are provided, they will be discarded.
You may only make requests that yield legal SPARQL XML or RDF output; the AllegroGraph extended syntax is therefore not available.
At present, the only supported verbs are SELECT
and ASK
.
results-format
to a remote query with the given verb
. if verb
is not provided, the intersection of :ask
and :select
(the two permitted values) is returned.