Query (QPF)#

Changed in version 2.0.

ESS provides a Query service that allows a Pod Owner (or other agents with Control access to the Pod) to query RDF (Resource Description Framework) data in the Pod. Specifically, ESS Query service provides a Quad Pattern Fragment (QPF) interface that the Pod Owner (or other agents with Control access to the Pod) can use to query RDF data.

Requirements#

Indexed Data#

To return data that match the query quad pattern, the RDF resource must be indexed by the Query service’s indexer.

To index Pod resources for querying, the indexer requires:

  1. Read access to the Resource.

    You can grant Read access specifically to the indexer using its WebID:

    https://fragments-indexer.{ESS DOMAIN}/id
    

    In addition, like any other agent, the indexer has Read access to those resources with Read access granted to the Public.

  2. Change notifications on the Resource.

    That is, once the indexer is given Read access to a Resource, a Resource change notification triggers the indexing of that Resource.

Important

Because the indexing occurs after the indexer consumes a change notification event, the query results lag behind the current state of the Resource. The delay amount depends on the lag in the notification queue.

Querying Agent Access#

Only Agents who have Control Read access to the root of the Pod, such as the Pod Owner, can access data from the QPF endpoint.

You can further specify which applications can query the endpoint by granting specific applications appropriate access.

UMA and Solid-OIDC Access Tokens#

For query access to the Pod, the ESS’ Query service can use either:

  • UMA token, or

  • Solid-OpenID Connect (OIDC) access token.

With the UMA authorization flow:

  1. When you issue your query without an access token, the Query service returns a 401 along with a ticket and authorization server in the WWW-Authenticate header.

  2. From the authorization server, the client can exchange the UMA ticket for the UMA access token.

    • To exchange the UMA ticket for the access token, the client must include its client_id.

  3. Include the access token in the header of your query request and retry.

Querying RDF Data#

RDF statements have the following form (also known as a triple):

<subject> <predicate> <object>

For a given Pod, ESS Query service allows the Pod Owner (or other agents with Control access to the Pod) to query the Pod’s RDF resources based on the QPF quad pattern selector; i.e., a combination of subject, predicate, object, and graph (where graph indicates the resource URL).

https://fragments.{ESS DOMAIN}/qpf?storage={POD}&subject={SUBJECT}&predicate={PREDICATE}&object={OBJECT}&graph={GRAPH}

Important

  • ESS Query service scopes its queries to a single Pod, specified in the storage query parameter.

  • ESS Query service returns results that may lag behind the current state of the Resources. For details, see Query Service Indexer and Query Response.

Query Parameters#

To query a Pod using QPF, you can specify the following query parameters to the service as part of a GET operation:

?storage={POD}&subject={SUBJECT}&predicate={PREDICATE}&object={OBJECT}&graph={GRAPH}

Tip

The Query service includes the Hypermedia Control as part of every result set. You can issue a GET to the service with only the storage parameter set (i.e., omit the data matching pattern parameters) to return just the Hypermedia Control.

The Hypermedia Control provides the supported query template and mapping of the QPF quad pattern selector parameters for querying data. Hypermedia Control acts as the definitive source.

The table of parameters is provided below only to complement the returned Hypermedia Control information.

Parameter

Description

storage

Required. URL of the Pod to query.

URL-encode the value.

If the storage parameter is omitted, ESS Query service returns a 400 Bad Request.

Note

  • storage is an ESS-specific parameter.

  • The querying agent must be either the Pod Owner or another agent with Control access to the Pod.

subject

The subject to match, as defined in the QPF quad pattern selector.

Triples with blank node values will be normalized into statements with URIs.

URL-encode the value.

predicate

The predicate to match, as defined in the QPF quad pattern selector.

URL-encode the value.

object

The object to match, as defined in the QPF quad pattern selector.

URL-encode the value.

graph

The graph (the URL of the Resource) to match, as defined in the QPF quad pattern selector.

URL-encode the value.

Query Response#

Important

The query results may lag behind the current state of the Resource. For more details, see Query Service Indexer.

The response includes:

For example:

@prefix foaf:  <http://xmlns.com/foaf/0.1/> .
@prefix hydra: <http://www.w3.org/ns/hydra/core#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix sd:    <http://www.w3.org/ns/sparql-service-description#> .
@prefix void:  <http://rdfs.org/ns/void#> .

_:b0 {
    <https://fragments.example.com/qpf?storage=https%3A%2F%2Fstorage.example.com%2Fa211ad26-zzzz-9999-8b20-acb3aed0e369%2F>
         void:subset   <https://fragments.example.com/qpf?storage=https%3A%2F%2Fstorage.example.com%2Fa211ad26-zzzz-9999-8b20-acb3aed0e369%2F&object=https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%23Article> ;
         hydra:search  [ hydra:mapping   [ hydra:property  sd:graph ;
                                           hydra:variable  "graph"
                                         ] ;
                         hydra:mapping   [ hydra:property  rdf:subject ;
                                           hydra:variable  "subject"
                                         ] ;
                         hydra:mapping   [ hydra:property  rdf:predicate ;
                                           hydra:variable  "predicate"
                                         ] ;
                         hydra:mapping   [ hydra:property  rdf:object ;
                                           hydra:variable  "object"
                                         ] ;
                         hydra:template  "https://fragments.example.com/qpf?storage=https%3A%2F%2Fstorage.example.com%2Fa211ad26-zzzz-9999-8b20-acb3aed0e369%2F{&graph,subject,predicate,object}"
                       ] .

    _:b0    foaf:primaryTopic  <https://fragments.example.com/qpf?storage=https%3A%2F%2Fstorage.example.com%2Fa211ad26-zzzz-9999-8b20-acb3aed0e369%2F&object=https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%23Article> .

    <https://fragments.example.com/qpf?storage=https%3A%2F%2Fstorage.example.com%2Fa211ad26-zzzz-9999-8b20-acb3aed0e369%2F&object=https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%23Article>
         void:subset            <https://fragments.example.com/qpf?storage=https%3A%2F%2Fstorage.example.com%2Fa211ad26-zzzz-9999-8b20-acb3aed0e369%2F&object=https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%23Article> ;
         void:triples           "10"^^<http://www.w3.org/2001/XMLSchema#long> ;
         hydra:next             <https://fragments.example.com/qpf?storage=https%3A%2F%2Fstorage.example.com%2Fa211ad26-zzzz-9999-8b20-acb3aed0e369%2F&object=https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%23Article&after=285896126> ;
         hydra:previous         <https://fragments.example.com/qpf?storage=https%3A%2F%2Fstorage.example.com%2Fa211ad26-zzzz-9999-8b20-acb3aed0e369%2F&object=https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%23Article&before=285896101> ;
         hydra:view             <https://fragments.example.com/qpf?storage=https%3A%2F%2Fstorage.example.com%2Fa211ad26-zzzz-9999-8b20-acb3aed0e369%2F&object=https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%23Article> ;
         foaf:isPrimaryTopicOf  _:b0 .
}

<https://storage.example.com/a211ad26-zzzz-9999-8b20-acb3aed0e369/readingLists/myList> {
    <https://storage.example.com/a211ad26-zzzz-9999-8b20-acb3aed0e369/readingLists/myList#title2>
            rdf:type  <https://www.w3.org/ns/activitystreams#Article> .

    <https://storage.example.com/a211ad26-zzzz-9999-8b20-acb3aed0e369/readingLists/myList#title0>
            rdf:type  <https://www.w3.org/ns/activitystreams#Article> .

    <https://storage.example.com/a211ad26-zzzz-9999-8b20-acb3aed0e369/readingLists/myList#title3>
            rdf:type  <https://www.w3.org/ns/activitystreams#Article> .

    <https://storage.example.com/a211ad26-zzzz-9999-8b20-acb3aed0e369/readingLists/myList#title1>
            rdf:type  <https://www.w3.org/ns/activitystreams#Article> .

    <https://storage.example.com/a211ad26-zzzz-9999-8b20-acb3aed0e369/readingLists/myList#title4>
            rdf:type  <https://www.w3.org/ns/activitystreams#Article> .
}

<https://storage.example.com/a211ad26-zzzz-9999-8b20-acb3aed0e369/readingLists/publicList> {
    <https://storage.example.com/a211ad26-zzzz-9999-8b20-acb3aed0e369/readingLists/publicList#title3>
            rdf:type  <https://www.w3.org/ns/activitystreams#Article> .

    <https://storage.example.com/a211ad26-zzzz-9999-8b20-acb3aed0e369/readingLists/publicList#title1>
            rdf:type  <https://www.w3.org/ns/activitystreams#Article> .

    <https://storage.example.com/a211ad26-zzzz-9999-8b20-acb3aed0e369/readingLists/publicList#title4>
            rdf:type  <https://www.w3.org/ns/activitystreams#Article> .

    <https://storage.example.com/a211ad26-zzzz-9999-8b20-acb3aed0e369/readingLists/publicList#title2>
            rdf:type  <https://www.w3.org/ns/activitystreams#Article> .

    <https://storage.example.com/a211ad26-zzzz-9999-8b20-acb3aed0e369/readingLists/publicList#title0>
            rdf:type  <https://www.w3.org/ns/activitystreams#Article> .
}

For more information, see Query Service.