FusekiStore — Apache Jena Fuseki RDF triplestore

Read this page in the documentation

FusekiStore — Apache Jena Fuseki RDF triplestore Overview Apache Jena Fuseki is a SPARQL server over the Jena RDF triplestore. It is not a SQL database: there are no rows, no DDL, and no identifier escaping. Data is a set of RDF triples (subject–predicate–object), queried and mutated entirely over HTTP using the SPARQL 1.1 Protocol. A Fuseki dataset exposes a query endpoint (/<dataset>/query) and an update endpoint (/<dataset>/update). Because none of that fits the SQL-shaped Dialect interface, FusekiStore implements the minimal NoSqlStore marker interface (src/nosql/store.ts) — connection lifecycle plus a getClient() escape hatch — and exposes SPARQL query/update operations directly rather than forcing them into a query(sql) shape. Identity: Property | Value | --------- | ---------- | name | 'fuseki' | library | 'fetch' | No canonical driver — HTTP over fetch Fuseki has no dedicated npm client; it is just a SPARQL/HTTP endpoint. Rather than depend on any package, this store talks to the server with the global fetch. The internal client (createFetchClient) POSTs the SPARQL text with Content-Type: application/sparql-query (queries, Accept: application/sparql-results+json) or application/sparql-update (updates). Injected client FusekiStoreOptions accepts a pre-built client implementing the small SparqlHttpClient interface. When provided it is used verbatim and endpoint is ignored; otherwise the internal fetch-based client is built against endpoint at connect() time. This is how the test suite injects a mock (no network). The query/update endpoint paths are derived from the dataset name: Getter | Value | Default (dataset = 'ds') | ------------- | --------------------- | -------------------------- | queryPath | /<dataset>/query | /ds/query | updatePath | /<dataset>/update | /ds/update | Connection Build a store from connection options and call connect(): All options are optional: Option | Type | Purpose | ---------- | ------------------------- | ------------------------------------------------------------------------------ | endpoint | string | Base URL of the Fuseki server. Defaults to http://localhost:3030. | dataset | string | Dataset name. Defaults to ds. Drives queryPath / updatePath. | client | SparqlHttpClient | Pre-built client used verbatim; when set, endpoint is ignored. | headers | Record<string, string> | Extra HTTP headers sent with every internal-client request. | Injected-client form Supply your own client (or a mock) to bypass the internal fetch transport: Methods Every SPARQL method resolves the client (throwing ConnectionError if not connected), POSTs via the client, and wraps any client failure in a DatabaseError (carrying the SPARQL text as sql). Lifecycle Method | Signature | Behavior | -------------- | ---------------------------------- | ---------------------------------------------------------------------------------------------- | connect | connect(): Promise<void> | Uses an injected client if provided, otherwise builds the internal fetch client. Idempotent. | disconnect | disconnect(): Promise<void> | Clears the client and connection state. | isConnected | isConnected(): boolean | true only when connected and a client is present. | getClient | getClient(): SparqlHttpClient | Returns the underlying (internal or injected) client. Throws ConnectionError if not connected. | SPARQL surface Method | Signature | Behavior | -------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | query | query(sparql: string): Promise<any[]> | Runs a SELECT/CONSTRUCT query against queryPath; returns body.results.bindings (or []). | ask | ask(sparql: string): Promise<boolean> | Runs an ASK query against queryPath; returns Boolean(body.boolean). | update | update(sparql: string): Promise<any> | Runs a SPARQL UPDATE (INSERT/DELETE/DROP/...) against updatePath; returns the client's response. | add | add(triples: string \| string[], graph?: string): Promise<any> | Issues INSERT DATA { ... }. Arrays are joined with newlines; when graph is given, wraps the body in GRAPH <g> { ... }. | drop | drop(graph?: string): Promise<any> | Issues DROP GRAPH <g> when a graph is given, else DROP ALL. | Example Verification status Unit / mock-verified only. The tests in tests/nosql/fuseki.test.ts are fully mock-driven: an in-memory SparqlHttpClient is injected via FusekiStoreOptions.client; it records each request (endpoint path + SPARQL body) and returns a canned SPARQL results envelope. There is no live Fuseki server and no network in the test run. What this proves: name/library are 'fuseki'/'fetch', and queryPath/updatePath derive from the dataset (/books/query, /books/update). query() POSTs to /ds/query and returns results.bindings; ask() returns the boolean; update() POSTs to /ds/update. add() emits INSERT DATA { <a> <b> <c> . } and wraps in GRAPH <urn:g> { ... } when a graph is passed; drop() emits DROP GRAPH <urn:g> / DROP ALL. Lifecycle: connect/disconnect (idempotent), getClient() returns the injected client, and ConnectionError before connect(). Error wrapping: client failures surface as DatabaseError. What this does not prove: live execution against a real Fuseki server. The request shape is verified against the SPARQL 1.1 Protocol contract, but end-to-end execution over the wire has not been exercised here. Related reading All data stores — the full catalogue, grouped by purpose Database types — where this sits among the 22 categories