https://github.com/D2KLab/sparql-transformer
A more handy way to use SPARQL data in your web app
https://github.com/D2KLab/sparql-transformer
json-ld linked-data sparql sparql-transformer transformer
Last synced: 19 days ago
JSON representation
A more handy way to use SPARQL data in your web app
- Host: GitHub
- URL: https://github.com/D2KLab/sparql-transformer
- Owner: D2KLab
- License: apache-2.0
- Created: 2018-01-02T14:37:28.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2024-08-29T14:05:17.000Z (over 1 year ago)
- Last Synced: 2025-09-04T13:51:43.915Z (3 months ago)
- Topics: json-ld, linked-data, sparql, sparql-transformer, transformer
- Language: JavaScript
- Homepage: https://d2klab.github.io/sparql-transformer/
- Size: 853 KB
- Stars: 47
- Watchers: 13
- Forks: 6
- Open Issues: 8
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Citation: CITATION.cff
Awesome Lists containing this project
- awesome-semantic-web - sparql-transformer - A generic JSON-LD transformer. (SPARQL / SPARQL Applications)
- awesome-semantic-web - sparql-transformer - A generic JSON-LD transformer. (Benchmarks / SPARQL Applications)
README
SPARQL Transformer
===================
Write your SPARQL query directly in the JSON-LD you would like to have in output.
JavaScript package. Try it with the [Playground](https://d2klab.github.io/sparql-transformer/).
> Looking for the [Python one](https://github.com/D2KLab/py-sparql-transformer)?
## News
- The parameter `$libraryMode` allows to perform the pagination on the merged objects, obtaining exactly `n=$limit` objects
- It is now possible to set a different **merging anchor** instead of `id`/`@id` using the `$anchor` modifier.
**Table of Contents**
- [Motivation](./motivation.md)
- [Query in JSON](#query-in-json)
- [How to use](#how-to-use)
- [Credits](#credits)
You want to learn more? Watch this [Tutorial](https://d2klab.github.io/swapi2020/slides.html)
## Query in JSON
The core idea of this module is writing in a single file the query and the expected output in JSON.
Two syntaxes are supported: plain JSON and JSON-LD.
Here the examples in the 2 formats for the query of cities.
- plain JSON
```json
{
"proto": [{
"id" : "?id",
"name": "$rdfs:label$required",
"image": "$foaf:depiction$required"
}],
"$where": [
"?id a dbo:City",
"?id dbo:country dbr:Italy"
],
"$limit": 100
}
```
- JSON-LD
```json
{
"@context": "http://schema.org/",
"@graph": [{
"@type": "City",
"@id" : "?id",
"name": "$rdfs:label$required",
"image": "$foaf:depiction$required"
}],
"$where": [
"?id a dbo:City",
"?id dbo:country dbr:Italy"
],
"$limit": 100
}
```
The syntax is composed by two main parts.
### The prototype
The `@graph`/`proto` property contains the prototype of the result as I expect it. When the value should be taken from the query result, I declare it using the following syntax:
$[$modifier[:option...]...]
The subject of the predicate is the variable (declared of automatically assigned) of the closer **mergin anchor** in the structure, which is the `@id`/`id` property (if it exists, otherwise is the default `?id`).
The SPARQL variable name is manually (with the `$var` modifier) or automatically assigned.
Some modifiers can be present after, separated by the `$` sign. The `:` prepend the options for a given modifier.
|MODIFIER|OPTIONS|NOTE|
|---|---|---|
|`$required`|n/a| When omitted, the clause is wrapped by `OPTIONAL { ... }`.|
|`$sample`|n/a|Extract a single value for that property by adding a `SAMPLE(?v)` in the SELECT|
|`$lang`|`:lang`[string, optional]| FILTER by language. In absence of a language, pick the first value of `$lang` in the root.
Ex. `$lang:it`, `$lang:en`, `$lang`. |
|`$bestlang`|`:acceptedLangs`[string, optional]| Choose the best match (using `BEST_LANGMATCH`) over the languages according to the list expressed through the [Accept-Language standard](https://tools.ietf.org/html/rfc7231#section-5.3.5). This list can be appended after the `:` or expressed as `$lang` in the root.
Ex. `$bestlang`, `$bestlang:en;q=1, it;q=0.7 *;q=0.1`|
|`$var`|`:var`[string]| Specify the variable that will be assigned in the query, so that it can be referred in the root properties (like `$filter`). If missing, a `?` is prepended.
Ex. `$var:myVariable`, `$var:?name`|
|`$anchor`|n/a|Set this property as merging anchor. The set is valid for the current level in the JSON tree, ignoring eventual `id`/`@id` sibling properties. Ex. `"a":"?example$anchor"` sets`?example` as subject of SPARQL statements and merges the final results on the `a` property.|
|`$reverse`|n/a|Set this property for use the current variable as subject of the SPARQL predicate, rather than object.|
|`$count` `$sum` `$min` `$max` `$avg`| n/a | Return the respective aggregate function (COUNT, SUM, MIN, MAX, AVG) on the variable. |
|`$langTag`|`"hide"`, `"show"` (default)| When `hide`, language tags are not included in the output.
Ex. `hide` => `"label":"Bologna"` ;
`show` => `"label":{"value": "Bologna", "language": "it"}` |
|`$accept`|`"string"`, `"number"`, `"boolean"`| If set, values of type different from the specified one are discarded. |
|`$alist`|n/a| When set, the interested property value would always be a list, even if with a single element.|
In this way, I specify a mapping between the JSON-LD output properties and the ones in the endpoint. The values non prepended by a `$` are transferred as is to the output.
### The root `$` properties
The `$`-something root properties allow to make the query more specific. They will be not present in the output, being used only at query level.
The supported properties are:
|PROPERTY|INPUT|NOTE|
|--------|-----|----|
|`$where`|string, array| Add where clause in the triple format.
Ex. `"$where": "?id a dbo:City"`|
|`$values`|object| Set `VALUES` for specified variables as a map. The presence of a lang tag or of the '$lang' attribute attached to the related property is taken in account.
Ex. `"$values": {"?id": ["dbr:Bari", "http://dbpedia.org/resource/Bologna"]}`|
|`$limit` |number| `LIMIT` the SPARQL results |
|`$limitMode` |`query` (default) or `library`| Perform the LIMIT operation in the query or on the obtained results (`library`) |
|`$from` |string(uri)| Define the graph `FROM` which selecting the results |
|`$offset` |number| `OFFSET` applied to the SPARQL results |
|`$distinct`|boolean (default `true`)| Set the `DISTINCT` in the select|
|`$orderby`|string, array| Build an `ORDER BY` on the variables in the input.
Ex. `"$orderby":["DESC(?name)","?age"]`|
|`$groupby`| string, array | Build an `GROUP BY` on the variables in the input.
Ex. `"$groupby":"?id"`|
|`$having`| string, array | Allows to declare the content of `HAVING`. If it is an array, the items are concatenated by `&&`. |
|`$filter`| string, array |Add the content as a `FILTER`.
`"$filter": "?myNum > 3"`|
|`$prefixes`| object | set the prefixes in the format `"foaf": "http://xmlns.com/foaf/0.1/"`.|
|`$lang`|`:acceptedLangs`[string]| The default language to use as `$bestlang` (see above), expressed through the [Accept-Language standard](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4).
Ex. `$lang:en;q=1, it;q=0.7 *;q=0.1`|
|`$langTag`|`"hide"`, `"show"` (default)| When `hide`, language tags are not included in the output. Similar to the inline `$langTag`, but acting at a global level.
Ex. `hide` => `"label":"Bologna"` ;
`show` => `"label":{"value": "Bologna", "language": "it"}` |
The `@context` property (for the JSON-LD version) will be transferred to the output.
The output of this query is intended to be:
- for the plain JSON, an array of object with the shape of the prototype;
- for the JSON-LD, an array of object with the shape of the prototype in the `@graph` property and with a sibling `@context`.
## How to use
#### Install in nodeJS
Install by npm.
```bash
npm install sparql-transformer
```
Add to the application.
```js
import sparqlTransformer from 'sparql-transformer';
```
#### Install in the browser
SPARQL Transformer is exposed as [ES Module](https://jakearchibald.com/2017/es-modules-in-browsers/). We rely on [getlibs](https://www.npmjs.com/package/getlibs) until the technology will allow to use ["bare" import specifier](https://github.com/WICG/import-maps#bare-specifiers).
```html
sparqlTransformer = System.import('https://unpkg.com/sparql-transformer')
```
#### Use
```js
sparqlTransformer(query, options)
.then(res => console.log(res))
.catch(err => console.error(err););
```
The first parameter (`query`) is the query in the JSON-LD format. The JSON-LD can be:
- an already parsed JS object (or defined real time),
- **ONLY if running in NodeJS**, the local path of a JSON file (that will then be read and parsed).
The `options` parameter is optional, and can define the following:
| OPTION | DEFAULT | NOTE |
| --- | --- | --- |
|context | http://schema.org/ | The value in `@context`. It overwrites the one in the query.|
| sparqlFunction | `null` | A function receiving in input the transformed query in SPARQL, returning a Promise. If not specified, the module performs the query on its own[1](#f1) against the specified endpoint. |
| endpoint | http://dbpedia.org/sparql | Used only if `sparqlFunction` is not specified. |
| debug | `false` | Enter in debug mode. This allow to print in console the generated SPARQL query. |
| params | `{}` | Additional parameters to pass to the HTTP query |
See [`test.js`](./test.js) for further examples.
## Credits
If you use this module for your research work, please cite:
> Pasquale Lisena, Albert Meroño-Peñuela, Tobias Kuhn and Raphaël Troncy. Easy Web API Development with SPARQL Transformer. In 18th International Semantic Web Conference (ISWC), Auckland, New Zealand, October 26-30, 2019.
[BIB file](./bib/lisena2019easyweb.bib)
> Pasquale Lisena and Raphaël Troncy. Transforming the JSON Output of SPARQL Queries for Linked Data Clients. In WWW'18 Companion: The 2018 Web Conference Companion, April 23–27, 2018, Lyon, France.
https://doi.org/10.1145/3184558.3188739
[BIB file](./bib/lisena2018sparqltransformer.bib)
---
1: Using a [lightweight SPARQL client](./src/sparql-client.mjs).