Comunica Tutorial - Advanced

Ruben Taelman, Joachim Van Herwegen

Portorož, Slovenia, 3 June 2019

Comunica Tutorial - Advanced

Ghent University – imec – IDLab, Belgium

Tutorial Website: http://bit.ly/eswcquery

A query engine is like a car

They both have swappable components

Hard-wiring of components

The easiest way to add components is by manually adding instances.

    const myCar = new Car();
    
    myCar.add(new EngineV8());
    
    myCar.add(new TireMichelin());
    myCar.add(new TireMichelin());
    myCar.add(new TireMichelin());
    myCar.add(new TireMichelin());
        

Downside: swapping components requires code changes.

Soft-wiring of components

Dependency Injection: Components are supplied by something external.

Components can be defined declaratively via a configuration file.

Comunica heavily makes use of dependency injection

Components.js: A dependency injection framework for JavaScript

Components are described in a semantic configuration file

→ A semantic layer on top of your source code

→ Configuration files could also be used for other programming languages

Comunica uses Components.js to wire actors, buses and mediators

Components.js Terminology

Module: Collection of components (e.g., a software package)

Component: Something that can be instantiated (e.g., a class)

Instance: An instantiated Component

A Module file describes a Module
and its Components

Module:
Component:

Comunica offers modules
for different query operators

Each module is published as a separate NPM package.

Each module is described in JSON-LD

We use import statements to refer to components in different files.

{
  "@context": …,
  "@id": "npmd:@comunica/actor-query-operation-distinct-hash",
  "@type": "Module",
  "requireName": "@comunica/actor-query-operation-distinct-hash",
  "import": [
    "files:components/Actor/QueryOperation/DistinctHash.jsonld",
    …
  ]
}
        

Components are described in JSON-LD

{
  …
  "components": [
    {
      "@id": "Actor/QueryOperation/DistinctHash",
      "requireElement": "ActorQueryOperationDistinctHash",
      "parameters": [
        {
          "@id":     "hashAlgorithm",
          "default": "sha1"
        },
        {
          "@id":     "digestAlgorithm",
          "default": "base64"
        }
    }
  ]
}
        

Why JSON-LD?

Components.js supports any kind of RDF serialization: Turtle, N-Triples, ...

For developers that are familiar with JSON

To achieve semantic RDF-based configurations:

The benefits of dereferencing

Modules, components and instances have a unique URL.

Others can reuse them by simply linking to them → distributed config files

Fetch them from anywhere (browser, query engine, ...)

npmd:@comunica/actor-query-operation-distinct-hash expands to https://linkedsoftwaredependencies.org/bundles/npm/%40comunica%2Factor-query-operation-distinct-hash/1.4.4/components/Actor/QueryOperation/DistinctHash.jsonld

A Config file instantiates components

Comunica describes instances in JSON-LD

{
  "@context": …,
  "@id": "urn:comunica:my",
  "actors": [
    {
      "@id":                    "#myDistinctQueryOperator",
      "@type":                  "ActorQueryOperationDistinctHash",
      "hashAlgorithm":          "RSA-SHA256"
    },
    {
      "@id":                    "#myConstructQueryOperator",
      "@type":                  "ActorQueryOperationConstruct"
    },
    …
  ]
}
        

Hands-on: creating a Comunica actor

Goal: Implementing, configuring, and using a custom REDUCED actor.

Hands-on: requirements

Hands-on: five steps

  1. Initialization of a Comunica engine: We provide an NPM package to start from.
  2. Creation of a new actor: JavaScript stub and module files.
  3. Actor configuration: Plugging in the actor via the config file.
  4. Logging configuration: Adding an existing logger to the config file.
  5. REDUCED implementation: Actual JavaScript implementation.

Each step can be skipped by checking out a different git tag.
For example, show the solution of step 2: git checkout tutorial-step/2