Triplestores

Requirements and configuration for using alternative SPARQL triplestores with LinkedDataHub

LinkedDataHub is designed to work with any SPARQL 1.1-compatible triplestore that supports the required protocols. While Apache Jena Fuseki is the default backend, you can use alternative triplestores by adding them as services in docker-compose.override.yml (without modifying the default docker-compose.yml). Browse available triplestore products at kgdev.net/products/.

Requirements

For a triplestore to work with LinkedDataHub, it must support the following:

Feature Required Description
SPARQL 1.1 Query ✅ Yes The triplestore must implement the SPARQL 1.1 Query specification
SPARQL 1.1 Update ✅ Yes The triplestore must implement the SPARQL 1.1 Update specification for data modifications
Graph Store Protocol (GSP) ✅ Yes The triplestore must support the SPARQL 1.1 Graph Store HTTP Protocol for graph-scoped operations.
Dataset-level CRUD protocol ⚪ No Support for RDF dataset-scoped CRUD operations, supported by stores such as Apache Fuseki. If not available, LinkedDataHub will fall back to graph-scoped GSP operations (slower but functional).
Authentication ⚪ No Either HTTP Basic authentication or Bearer token authentication (or both). See authentication below for configuration details.

Service configuration

Services are configured in config/system.trig using three key properties. See the dataspace reference for the full list of service properties.

sd:endpoint
The SPARQL Protocol endpoint URI (for SPARQL Query and Update operations)
Example: <http://qlever-host:7001/>
a:graphStore
The Graph Store Protocol endpoint URI (for graph-scoped CRUD operations)
Example: <http://qlever-host:7001/>
Required for all triplestores
a:quadStore
The quad store endpoint URI (for dataset-level CRUD operations)
Optional — if omitted, LinkedDataHub will use graph-scoped GSP fallback
Example: <http://fuseki-host:3030/ds/> (Fuseki-specific)

GSP fallback mode

When a:quadStore is not provided, LinkedDataHub automatically uses graph-scoped Graph Store Protocol operations instead. This mode:

  • Works with triplestores that don't support dataset-level TriG/N-Quads uploads
  • Loads data graph-by-graph rather than as a complete dataset
  • Takes longer during bootstrap (more HTTP requests) but is functionally equivalent
  • Is required for QLever, Tentris, and other GSP-only triplestores

Authentication

LinkedDataHub supports two authentication methods for SPARQL services, both configured in secrets/credentials.trig. See the configuration reference for the credentials secret entry.

HTTP basic authentication

Configure username and password using the a:authUser and a:authPwd properties:

@prefix a: <https://w3id.org/atomgraph/core#> .

<urn:linkeddatahub:services/end-user>
{
    <urn:linkeddatahub:services/end-user> a:authUser "username" ;
        a:authPwd "password" .
}

<urn:linkeddatahub:services/admin>
{
    <urn:linkeddatahub:services/admin> a:authUser "username" ;
        a:authPwd "password" .
}

Bearer token authentication

For triplestores that require Bearer token authentication (like QLever), configure the token using the a:authToken property:

@prefix a: <https://w3id.org/atomgraph/core#> .

<urn:linkeddatahub:services/end-user>
{
    <urn:linkeddatahub:services/end-user> a:authToken "your-bearer-token" .
}

<urn:linkeddatahub:services/admin>
{
    <urn:linkeddatahub:services/admin> a:authToken "your-bearer-token" .
}

This file is mounted as a Docker secret and is NOT committed to git (the /secrets folder is gitignored).

QLever configuration example

QLever is a high-performance triplestore optimized for text search. Here's how to configure LinkedDataHub to use QLever:

  1. Update config/system.trig to point to your QLever instance:

    @prefix lapp: <https://w3id.org/atomgraph/linkeddatahub/apps#> .
    @prefix a:    <https://w3id.org/atomgraph/core#> .
    @prefix ldt:  <https://www.w3.org/ns/ldt#> .
    @prefix sd:   <http://www.w3.org/ns/sparql-service-description#> .
    @prefix dct:  <http://purl.org/dc/terms/> .
    
    # Admin app - type + service binding
    
    <urn:linkeddatahub:apps/admin>
    {
        <urn:linkeddatahub:apps/admin> a lapp:AdminApplication ;
            ldt:service <urn:linkeddatahub:services/admin> .
    }
    
    # Admin service - QLever
    
    <urn:linkeddatahub:services/admin>
    {
        <urn:linkeddatahub:services/admin> a sd:Service ;
            dct:title "LinkedDataHub admin service (QLever)" ;
            sd:supportedLanguage sd:SPARQL11Query, sd:SPARQL11Update ;
            sd:endpoint <http://qlever-host:7001/> ;
            a:graphStore <http://qlever-host:7001/> .
            # Note: a:quadStore omitted - QLever uses GSP fallback mode
    }
    
    # End-user app - type + service binding
    
    <urn:linkeddatahub:apps/end-user>
    {
        <urn:linkeddatahub:apps/end-user> a lapp:EndUserApplication ;
            ldt:service <urn:linkeddatahub:services/end-user> .
    }
    
    # End-user service - QLever
    
    <urn:linkeddatahub:services/end-user>
    {
        <urn:linkeddatahub:services/end-user> a sd:Service ;
            dct:title "LinkedDataHub service (QLever)" ;
            sd:supportedLanguage sd:SPARQL11Query, sd:SPARQL11Update ;
            sd:endpoint <http://qlever-host:7001/> ;
            a:graphStore <http://qlever-host:7001/> .
            # Note: a:quadStore omitted - QLever uses GSP fallback mode
    }

    The a:quadStore property is omitted because QLever does not support dataset-level TriG/N-Quads uploads. LinkedDataHub will automatically fall back to using graph-scoped Graph Store Protocol operations (see service configuration).

  2. Configure Bearer token authentication (QLever requires this for write operations):

    Create secrets/credentials.trig with your QLever access token:

    @prefix a: <https://w3id.org/atomgraph/core#> .
    
    <urn:linkeddatahub:services/end-user>
    {
        <urn:linkeddatahub:services/end-user> a:authToken "your-qlever-bearer-token" .
    }
    
    <urn:linkeddatahub:services/admin>
    {
        <urn:linkeddatahub:services/admin> a:authToken "your-qlever-bearer-token" .
    }

    See bearer token authentication for details.

  3. Uncomment the credentials secret in docker-compose.yml:

    services:
      linkeddatahub:
        secrets:
          # ... other secrets ...
          - credentials  # Uncomment this line
  4. Start LinkedDataHub:

    docker-compose up --build

    During bootstrap, LinkedDataHub will load the default datasets using graph-scoped GSP operations. This takes longer than quad store mode but is functionally equivalent.

Troubleshooting

Bootstrap fails with HTTP 400 "application/trig not supported"
Your triplestore doesn't support dataset-level uploads. Remove the a:quadStore property from your service configuration to use GSP fallback mode.
Bootstrap fails with HTTP 401 or 403
Check your authentication configuration. Both Bearer token and HTTP Basic auth are configured in secrets/credentials.trig. See authentication for details.
Queries work but data import fails
Ensure your triplestore supports SPARQL 1.1 Update and Graph Store Protocol, not just Query. Check the triplestore requirements.
Connection refused errors
Check that the endpoint URLs are reachable from the LinkedDataHub Docker container. If running QLever in Kubernetes, use port-forwarding or set up proper networking.

For more details, see GitHub issue #272 which documents the QLever integration process.