RDF4J / SPARQL Endpoint
Waratah serves an RDF4J-protocol REST facade (waratah_api, axum) over an
in-process compute node. In the developer cluster the base URL is
http://127.0.0.1:8080/rdf4j/ and the single repository id is main.
There is no authentication in v1. There is also no CORS — proxy /rdf4j and
/waratah onto the same origin as your client (the bundled console does
exactly that), or use the same-origin /cors_proxy/{compute_id}/… route the
cluster exposes.
Endpoints
| Path | Methods | Purpose |
|---|---|---|
|
GET |
RDF4J protocol version. |
|
GET |
Repository list as SPARQL Results ( |
|
GET, POST |
SPARQL Protocol query endpoint. The query text arrives in the |
|
GET |
Repository quad count. |
|
GET, POST |
Plan explain — the HTTP twin of |
|
GET |
Namespace prefix listing. |
Everything else in the RDF4J surface — /statements, /contexts,
/rdf-graphs/…, /transactions, per-prefix namespace operations, and
PUT/DELETE on the repository resource — answers 501 not implemented.
SPARQL Update (INSERT DATA) does not exist in v1; data arrives via
the ingest API or waratah import.
curl -G 'http://127.0.0.1:8080/rdf4j/repositories/main' \
--data-urlencode 'query=SELECT ?s ?p ?o WHERE { ?s ?p ?o } LIMIT 5' \
-H 'Accept: text/csv'
Content negotiation
Content negotiation (waratah_api/src/serialize.rs) picks the first
acceptable Accept entry — q-values are ignored. Wildcards map to a
producible default (text/* → Turtle or CSV, application/* → RDF-XML or
JSON). An Accept listing only unproducible media types is a 406.
| Query form | Formats |
|---|---|
|
SPARQL Results JSON, XML, CSV, TSV |
|
Turtle, N-Triples, TriG, N-Quads, RDF-XML, JSON-LD |
Defaults on the results endpoint (SELECT / ASK) for absent / * /
*/* Accept: CSV (text/ also maps to CSV, application/ to
JSON). Graph responses (CONSTRUCT / DESCRIBE) default to Turtle for absent,
*/*, or text/* Accept, and application/ to RDF-XML — a
bare * is *not matched for graphs, so an Accept of only that is a
406. Repository and namespace listings keep the JSON default.
Compression
Responses are compressed by a hand-rolled axum middleware wrapping the whole
router: brotli at level 4, gzip at level 5. Accept-Encoding negotiation
follows RFC 9110 q-values (x-gzip aliases gzip, * stands in for
unlisted codings); equal-weight ties prefer brotli; a header rejecting every
coding including identity short-circuits 406 before the handler runs.
Compressed responses carry Content-Encoding and Vary: Accept-Encoding;
streamed SELECT bodies compress chunk-by-chunk. Bodies already carrying
Content-Encoding (CORS-proxy pass-through) are never recompressed,
image/* (except SVG) and text/event-stream are skipped, and buffered
bodies under 1025 bytes stay identity — which keeps ASK booleans
uncompressed in every serialization.
Also served on the same listener
-
The pre-built grevillea console (static SPA) at
/—GET/HEADfallback after the/rdf4j,/waratah, and/cors_proxynests. A missing console artifact embeds a stub andwaratah startwarns. -
/waratah/*— admin surface: ingest and cluster snapshot / health. -
/cors_proxy/{compute_id}/rdf4j|waratah/…— streams the request and response to that cluster member’s configured HTTP origin, so a browser UI can reach peer computes same-origin. Each compute’sGET /waratah/clusterrow carries itscors_proxybase. -
/jupyter/*— the optional notebook sidecar reverse proxy (REST
WebSocket kernel channels), whenwaratah start --with-notebooks(orwaratah standalone --with-notebooks) is on.
Every live process also reports a semver+git-describe version string via
its Describe RPC, surfaced on GET /waratah/cluster — see
the Cluster API page.