Passing a context


On this page

    When passing a query to a Comunica query engine, you can pass additional information to the engine using a context object.

    1. How to use the context

    When querying in a JavaScript application, the context must be passed as second argument to the query() method of a Comunica engine.

    For example, a context that defines the sources to query over is passed as follows:

    const QueryEngine = require('@comunica/query-sparql').QueryEngine;
    const myEngine = new QueryEngine();
    
    const bindingsStream = await myEngine.queryBindings(`SELECT * WHERE { ?s ?p ?o }`, {
      sources: ['https://fragments.dbpedia.org/2015/en'],
    });
    

    The sources field is the only entry that is required in the context. All other entries that are discussed hereafter are optional.

    During query execution, the context is converted into an immutable object to ensure that the original context entries remain unchanged during the whole query execution.

    2. Overview

    The following table gives an overview of all possible context entries that can be passed.

    KeyDescription
    sourcesAn array of data sources
    destinationA data destination for update queries
    lenientIf HTTP and parsing failures are ignored
    initialBindingsVariables that have to be pre-bound to values in the query
    queryFormatThe provided query's format
    baseIRIBase IRI for relative IRIs in SPARQL queries
    logA custom logger instance
    datetimeSpecify a custom date
    httpProxyHandlerA proxy for all HTTP requests
    httpIncludeCredentials(browser-only) If current credentials should be included for HTTP requests
    httpAuthHTTP basic authentication value
    httpTimeoutHTTP timeout in milliseconds
    httpBodyTimeoutMakes the HTTP timeout apply until the response is fully consumed
    httpRetryCountThe number of retries to perform on failed fetch requests
    httpRetryDelayThe number of milliseconds to wait between fetch retries
    httpRetryOnServerErrorIf fetch should be retried on 5xx server error responses, instead of being resolved.
    recoverBrokenLinksUse the WayBack machine to recover broken links
    extensionFunctions or extensionFunctionCreatorSPARQL extension functions
    fetchA custom fetch function
    readOnlyIf update queries may not be executed
    explainThe query explain mode
    unionDefaultGraphIf the default graph should also contain the union of all named graphs
    localizeBlankNodesIf blank nodes should be localized per bindings entry

    When developing Comunica modules, all context entry keys can be found in @comunica/context-entries.

    3. Defining sources

    Using the sources context entry, data sources can be defined that Comunica should query over. The value of this must be an array, where the array may contain both strings or objects:

    • Array elements that are strings are interpreted as URLs, such as 'https://www.rubensworks.net/' or 'https://fragments.dbpedia.org/2016-04/en'.
    • Object array elements can be different things:
      • A hash containing type and value, such as { type: 'sparql', value: 'https://dbpedia.org/sparql' }.
      • An RDF/JS source object, such as new N3Store().

    String-based sources will lead to Comunica trying to determine their source type automatically. Hash-based sources allows you to enforce a specific source type.

    Learn more about all available source type.
    Some SPARQL endpoints may be recognised as a file instead of a SPARQL endpoint due to them not supporting SPARQL Service Description, which may produce incorrect results. For these cases, the sparql type MUST be set.

    For example, all of the following source elements are valid:

    const bindingsStream = await myEngine.queryBindings(`...`, {
      sources: [
        'https://fragments.dbpedia.org/2015/en',
        { type: 'hypermedia', value: 'https://fragments.dbpedia.org/2016/en' },
        { type: 'file', value: 'https://www.rubensworks.net/' },
        new N3Store(),
        { type: 'sparql', value: 'https://dbpedia.org/sparql' },
      ],
    });
    

    4. Defining an update destination

    If you are executing an update query over more than one source, then you need to specify the destination of the resulting update. More details on this can be found in the guide on updating in a JavaScript app.

    5. Lenient execution

    By default, Comunica will throw an error when it encounters an invalid RDF document or HTTP URL. It is possible to ignore these errors and make Comunica ignore such invalid documents and URLs by setting lenient to true:

    const bindingsStream = await myEngine.queryBindings(`SELECT * WHERE { ?s ?p ?o }`, {
      sources: ['https://fragments.dbpedia.org/2015/en'],
      lenient: true,
    });
    

    6. Binding variables

    Using the initialBindings context entry, it is possible to bind certain variables in the given query to terms before the query execution starts. This may be valuable in case your SPARQL query is used as a template with some variables that need to be filled in.

    This can be done by passing an RDF/JS Bindings object as value to the initialBindings context entry:

    import { BindingsFactory } from '@comunica/utils-bindings-factory';
    import { DataFactory } from 'rdf-data-factory';
    
    const DF = new DataFactory();
    const BF = new BindingsFactory();
    
    const bindingsStream = await myEngine.queryBindings(`SELECT * WHERE {
      {?s ?p ?template1 } UNION { ?s ?p ?template2 }
    }`, {
      sources: ['https://fragments.dbpedia.org/2015/en'],
      initialBindings: BF.fromRecord({
        template1: factory.literal('Value1'),
        template2: factory.literal('Value2'),
      }),
    });
    

    Bindings can be created using any RDF/JS BindingsFactory, such as @comunica/utils-bindings-factory. Learn more about the creation of these bindings objects in the bindings guide.

    7. Setting the query format

    By default, queries in Comunica are interpreted as SPARQL queries. As such, the queryFormat entry defaults to { language: 'sparql', version: '1.1' }.

    Since Comunica is not tied to any specific query format, it is possible to change this to something else, such as { language: 'graphql', version: '1.0' }. More information on this can be found in the GraphQL-LD guide.

    8. Setting a Base IRI

    Terms in SPARQL queries can be relative to a certain Base IRI. Typically, you would use the BASE keyword in a SPARQL query to set this Base IRI. If you want to set this Base IRI without modifying the query, then you can define it in the context using baseIRI:

    const bindingsStream = await myEngine.queryBindings(`SELECT * WHERE {
      ?s </relative> ?o
    }`, {
      sources: ['https://fragments.dbpedia.org/2015/en'],
      baseIRI: 'http://example.org/',
    });
    

    9. Enabling a logger

    A logger can be set using log. More information on this can be found in the logging guide.

    10. Setting a custom date

    Using datetime, a custom date can be set in Comunica. The range of this field must always be a JavaScript Date object:

    const bindingsStream = await myEngine.queryBindings(`SELECT * WHERE { ?s ?p ?o }`, {
      sources: ['https://fragments.dbpedia.org/2015/en'],
      date: new Date(),
    });
    

    This date is primarily used for the SPARQL NOW() operator. It is also used when performing time travel querying using the Memento protocol.

    11. Enabling an HTTP proxy

    All HTTP requests can be run through a proxy using httpProxyHandler. More information on this can be found in the HTTP proxy guide.

    12. Include credentials in HTTP requests

    Only applicable when running in the browser

    If this option is enabled, then all cross-site requests will be made using credentials of the current page. This includes cookies, authorization headers or TLS client certificates.

    Enabling this option has no effect on same-site requests.

    const bindingsStream = await myEngine.queryBindings(`SELECT * WHERE { ?s ?p ?o }`, {
      sources: ['https://fragments.dbpedia.org/2015/en'],
      httpIncludeCredentials: true,
    });
    

    13. Send requests via HTTP basic authentication

    Via HTTP Basic Authentication one can include username and password credentials in HTTP requests. More information on this can be found in the HTTP basic authentication guide.

    14. SPARQL extension functions

    SPARQL allows non-standard, custom extension functions to be used within queries. In order to provide an implementation to these extension functions, Comunica allows developers to plug them in via the context. More information on this can be found in the SPARQL extension functions guide.

    15. Using a custom fetch function

    By default, Comunica will use the built-in fetch function to make HTTP requests. It is however possible to pass a custom function that will be used instead for making HTTP requests, as long as it follows the Fetch API.

    This can be done as follows:

    const bindingsStream = await myEngine.queryBindings(`SELECT * WHERE { ?s ?p ?o }`, {
      sources: ['https://fragments.dbpedia.org/2015/en'],
      fetch: myfetchFunction,
    });
    

    If you want to perform authenticated HTTP requests for Solid, you may want to consider using Comunica Solid.

    16. HTTP Timeout

    By default Communica does not apply any timeout on the HTTP requests done to external services. It is possible to add a timeout using the httpTimeout option which value is the timeout delay in milliseconds. For example to add an HTTP timeout of 60s:

    const bindingsStream = await myEngine.queryBindings(`SELECT * WHERE { ?s ?p ?o }`, {
      sources: ['https://fragments.dbpedia.org/2015/en'],
      httpTimeout: 60_000,
    });
    

    It is also possible to make this timeout not only apply until the response starts streaming in but until the response body is fully consumed using the httpBodyTimeout boolean option. It is useful to limit cases like very long response streams:

    const bindingsStream = await myEngine.queryBindings(`SELECT * WHERE { ?s ?p ?o }`, {
      sources: ['https://fragments.dbpedia.org/2015/en'],
      httpTimeout: 60_000,
      httpBodyTimeout: true
    });
    

    17. Union Default Graph

    By default, Comunica will only query over the default graph. If you want to query over triples in other named graphs, you need to specify this via the GRAPH, FROM, or FROM NAMED clauses. However, by setting the unionDefaultGraph context option to true, triples patterns will also apply to triples in the non-default graph.

    const bindingsStream = await myEngine.queryBindings(`SELECT * WHERE { ?s ?p ?o }`, {
      sources: ['https://fragments.dbpedia.org/2015/en'],
      unionDefaultGraph: true,
    });
    

    18. HTTP Retries

    Using the httpRetryOnServerError, httpRetryCount, and httpRetryDelay options, you can make your engine retry requests for a number of times if the server produces an error for it.

    const bindingsStream = await myEngine.queryBindings(`SELECT * WHERE { ?s ?p ?o }`, {
      sources: ['https://fragments.dbpedia.org/2015/en'],
      httpRetryOnServerError: true,
      httpRetryCount: 3,
      httpRetryDelay: 100,
    });
    

    The recoverBrokenLinks option can make your engine fall back to the WayBack Machine if a document has become unavailable.

    const bindingsStream = await myEngine.queryBindings(`SELECT * WHERE { ?s ?p ?o }`, {
      sources: ['http://xmlns.com/foaf/spec/20140114.rdf'],
      recoverBrokenLinks: true,
    });
    

    20. Deduplicate quads in construct queries

    The distinctConstruct option can remove duplicate quads from CONSTRUCT query outputs. This corresponds to placing a DISTINCT onto a CONSTRUCT operator (which is not allowed by the SPARQL specification).

    const bindingsStream = await myEngine.queryBindings(`CONSTRUCT WHERE { ?s1 ?p1 ?o1. ?s2 ?p2 ?o2 }`, {
      sources: ['https://fragments.dbpedia.org/2015/en'],
      distinctConstruct: true,
    });