The execution of SPARQL queries can be challenging for a number of reasons including performance, availability, and reproducibility. To encourage greater reproducibility, sharability, and performance of these queries, a result caching approach offers a pragmatic solution. This specification defines SPARQL Query View Materialization Containers (QVMC): HTTP resources that implement the Linked Data Platform (LDP) Container model to store SPARQL query definitions and their corresponding materialized result sets. A QVMC is an ldp:BasicContainer whose members include SPARQL query source files and SPARQL Results documents. An RDF index resource describes the contained views and how they were generated. These guidelines enable clients and tools to reliably leverage cached SPARQL queries, their canonical algebra, provenance, and serialized results, in a way that promotes interoperability and reuse.

Introduction

This document discusses the canonical view materialization of SPARQL queries and results. This document is primarily intended for the following audiences:

The goals of this specification are to:

To understand the basics in this note ... (knowledge requirements) The SPARQL Query Cache (SQC) is a conventional layout for representing cached SPARQL queries and their results as HTTP resources inside an ldp:Container. Each cached query is addressed by a stable, opaque identifier derived from a cache key function over the query text, dataset/endpoint selection, and selected request headers. The cache also stores a canonical SPARQL algebra form and a serialized result set for deterministic reuse.

Terminology

Key terms are used as defined in the following specifications: Linked Data Platform (LDP), SPARQL 1.1 Query, SPARQL Results JSON and XML.

QVMC
SPARQL Query View Materialization Container (this spec).
Index
The RDF document queries.ttl at the root of a QVMC.

RFC 2119 keywords (MUST, SHOULD, MAY) indicate conformance requirements.

The following prefixes are used throughout the document.

        PREFIX rdfs: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
        PREFIX prov: <http://www.w3.org/ns/prov#> .
        PREFIX dc: <http://purl.org/dc/terms/> .
        PREFIX sh: <http://www.w3.org/ns/shacl#> .
        PREFIX tq: <http://www.w3.org/2001/sw/DataAccess/tests/test-query#> .
        PREFIX tm: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> .
        PREFIX sd: <http://www.w3.org/ns/sparql-service-description#> .
        PREFIX se: <https://purl.expasy.org/sparql-examples/ontology#> .
        PREFIX qvmc: <https://vocab.example/qvmc#> .
      

Container Model

A SPARQL query execution, from the perspective of the user, consists of four distinct componenets.

This section introduces a materialization approach to record the serialization of each of these components of a SPARQL query execution, which enables the consistent accessing and utilization of these data for users and applications.

Resource types

A QVMC MUST be an HTTP-accessible ldp:BasicContainer and MUST advertise Link: <http://www.w3.org/ns/ldp#BasicContainer> ; rel="type" in responses to GET on the container URI. Servers SHOULD also include ldp:contains statements in RDF representations.

Members

The members of a QVMC are:

Additional non-normative artifacts (e.g., CSV extracts) MAY be present but are out of scope.

Naming and layout

        GET /views/ HTTP/1.1
        Accept: text/turtle
        HTTP/1.1 200 OK
        Link: <http://www.w3.org/ns/ldp#BasicContainer> ; rel="type"
        Content-Type: text/turtle; charset=utf-8

        @prefix ldp: <http://www.w3.org/ns/ldp#> .
        @prefix dc: <http://purl.org/dc/terms/> .
        @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

         a ldp:BasicContainer ;
          dc:title "SPARQL Query Materialization Container" ;
          ldp:contains </views/queries.ttl> ,
            </views/hash1.rq> ,
            </views/hash1.srj> ,
            # ... more members ...
          .
      

File formats

Container Index

The container includes an index file, queries.ttl, which is a Turtle graph that describes each stored SPARQL query entry using terms from SPARQL 1.1, SHACL, and Service Description.

Data model

The following classes and properties are used:

  • tq:QueryForm — a materialized view entry.
  • dct:title, dct:description, dct:modified — human-readable metadata.
  • tq:QuerySelect — the supported SPARQL query operation.
  • sh:SPARQLExecutable - designates that this hash contains a link to the .rq file.
  • tq:query (IRI) — link to the .rq file.
  • sh:select (literal) — the entry's SPARQL query algebra (identical to that in the entry's .rq file).
  • tm:result (IRI) — link to the .srj or .srx file.
  • sd:endpoint (IRI) — link to the RDF list containing the target sources of the query entry (sources must be valid URIs).
  • dct:created (xsd:dateTime) — timestamp of when the query was executed.
  • qvmc:status (literal; values: current | stale | failed) — indicates the current state of the query entry results.
  • prov:wasGeneratedBy — blank node with provenance information about the query entry.

The index resource itself SHOULD be typed as qvmc:Index and ldp:RDFSource and may carry container-level metadata.

Index shape and constraints

Each tq:QueryForm entry MUST include at least tq:query, tm:result, sd:endpoint, and dct:created. The pair (tq:query, tm:result) MUST be unique within the container. sd:endpoint MUST be a valid RDF list of one or more URIs. dct:created MUST be in xsd:dateTime. qvmc:status MUST be a literal in the range: current | stale | failed. prov:wasGeneratedBy MUST include a prov:Activity with at least prov:used and prov:modified.

It is recommended that each tq:QueryForm SPARQL query entry is identified by an opaque, 10-character token (e.g., #aBc1d2Ef3g) composed of integers (0-9) and both lowercase and uppercase letters (a-z, A-Z). This hash is used as a key to refer to a singular stored SPARQL query entry. At a minimum, each tq:QueryForm entry MUST be unique within the queries.ttl file.

SPARQL query file serialization (.rq)

Each SPARQL query entry includes a serialization of the SPARQL algebra for the query, stored in a file named {hash}.rq.

  • MUST be named to match the source query entry's {hash}.
  • MUST declare media type application/sparql-query.
          PREFIX : <https://example.org/ontology/>
          SELECT ?s ?score WHERE { ?s :score ?score } ORDER BY DESC(?score) LIMIT 10
        

Results file serialization

Each SPARQL query entry includes a serialization of the results for the query, stored in a file named {hash}.* (where "*" is the descriptive extension of the file-type respresented).

  • MUST be named to match the source query's {hash}.
  • MUST use either SPARQL Results JSON (application/sparql-results+json) or SPARQL Results XML (application/sparql-results+xml) serialization formats.

Example - queries.ttl

          @prefix rdfs: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
          @prefix prov: <http://www.w3.org/ns/prov#> .
          @prefix qvmc: <https://vocab.example/qvmc#> .
          @prefix dc: <http://purl.org/dc/terms/> .
          @prefix sh: <http://www.w3.org/ns/shacl#> .
          @prefix tq: <http://www.w3.org/2001/sw/DataAccess/tests/test-query#> .
          @prefix tm: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> .
          @prefix sd: <http://www.w3.org/ns/sparql-service-description#> .
          @prefix se: <https://purl.expasy.org/sparql-examples/ontology#> .
          @base <https://data.example.org/example/> .

          <#index> a qvmc:Index ;
          dc:title "SPARQL Query Materialization Container Example" ;
          dc:modified "2025-09-25T09:00:00Z"^^xsd:dateTime .

          <#aBc1d2Ef3g> a tq:QueryForm, tq:QuerySelect, sh:SPARQLExecutable ;
            dc:title "Top 10 by score" ;
            dc:description "Returns 10 entities with the highest :score." ;
            tq:query <aBc1d2Ef3g.rq> ;
            tm:result <aBc1d2Ef3g.srj> ;
            sh:select "SELECT ?s ?score WHERE { ?s :score ?score } ORDER BY DESC(?score) LIMIT 10" ;
            sd:endpoint <#5926e69f-c619-4029-b516-21affc0598e0> ;
            dc:created "2025-09-24T16:12:03Z"^^xsd:dateTime ;
            qvmc:status "current" ;
            prov:wasGeneratedBy [
              a prov:Activity ;
              prov:used <aBc1d2Ef3g.rq>, <#5926e69f-c619-4029-b516-21affc0598e0> ;
              prov:modified "2025-09-24T16:12:03Z"^^xsd:dateTime
            ] .

          <#5926e69f-c619-4029-b516-21affc0598e0> rdfs:first <https://sparql.example.org/sparql/> ;
            rdfs:rest rdfs:nil .
        
The order in which RDF triples occur in an RDF dataset convey no meaning.

Security & privacy considerations

  • The discussed container and resource structure is designed to be configured with any additional access controls at a user's discretion.
  • Consider cache-control headers for implementations where access controls are used and stored data should not be cached by intermediaries.
  • Endpoints and dataset IRIs in the index may reveal infrastructure; redact if necessary.

HTTP interactions

Security and Privacy Note: If access controls are implemented, the following operations are permitted only if authorization is successful:

  • Implementations MUST expose the container as an ldp:BasicContainer with GET and POST/PUT access rights on all resources for at least one authorized user.
  • Implementations MAY support authenticated GET and POST/PUT methods to other authenticated users and/or the public.

Updating the index

Implementations MUST update queries.ttl atomically when new members are added, deleted, or modified. The following describes the requirements for each action:

  • Add: When a new query entry is added, create a new tq:QueryForm node with a new unique subject IRI <#${name}>. Both results and query serialization files SHOULD be named <#${name}.rq> and <#${name}.*> respectively after the <#${name}> of the tq:QueryForm node. Set sd:endpoint to an RDF list of one or more source URIs that the query targets. Set dc:created to the creation timestamp.
  • ...
  • Modify: For an existing query entry, if the dataset changes or a new execution of the same SPARQL query over the same sources gives different results, update the qvmc:status of the relevant tq:QueryForm node to stale. IMPORTANT if the results of the query change, users SHOULD create a new query entry instead of modifying the existing one to preserve provenance. In this case, the pre-existing entry's qvmc:status MUST be set to stale and the triple qvmc:linkedQuery <#${updated-entry-name}> MUST be added. Whenever a field within an entry is updated, users MUST update prov:wasGeneratedBy with a new timestamp via dc:modified.
  • Delete: When a query entry is deleted, remove the corresponding tq:QueryForm node and all references to its associated files (.rq, .srj, .srx) from queries.ttl. Optionally, remove the files themselves from the container.
          PATCH /views/queries.ttl HTTP/1.1
          Content-Type: application/sparql-update

          DELETE { <#aBc1d2Ef3g> dct:modified ?t ; qvmc:status ?s }
          INSERT { <#aBc1d2Ef3g> dct:modified "2025-09-25T10:01:22Z"^^xsd:dateTime ; qvmc:status "current" }
          WHERE { OPTIONAL { <#aBc1d2Ef3g> dct:modified ?t ; qvmc:status ?s } }
        

Extensibility

The index graph MAY include additional metadata such as provenance (dct:source), execution timing, result counts, or dataset snapshots. Unknown properties MUST be ignored by consumers.

Conformance

A QVMC Server conforms to this specification if it exposes a container satisfying the requirements in Container model, enforces media types in File formats, and maintains a valid queries.ttl as described in The index.

A QVMC Client conforms if it manipulates members through LDP operations and creates/patches queries.ttl entries according to the data model.

Implementation guidance (non-normative)

Change log (non-normative)