A SPARQL micro-service resides in a dedicated folder named after the convention: <Web API>/<micro-service>
, e.g. flickr/getPhotosByTags_sd.
It can be configured following two different flavours that each correspond to a method for passing arguments to the micro-service:
Configuration method | Argument-passing method |
---|---|
config.ini property file |
HTTP query string parameters |
ServiceDescription.ttl RDF document |
Terms of the SPARQL query graph pattern |
These two methods are described in the first two sections below. Whatever the configuration method, a SPARQL micro-serivce describes how to map responses from the Web API to RDF triples using (1) a JSON-LD profile and optionally (2) a SPARQL CONSTRUCT query. This is explained in section Mapping a Web API response to RDF triples.
Table of contents:
- Configuration with file config.ini
- Configuration with a SPARQL Service Description file
- Re-injecting arguments in the graph produced by the micro-service
- Passing multiple values for the same argument
- Mapping a Web API response to RDF triples
In this configuration method, the micro-service folder is organized as follows:
config.ini # micro-service configuration
profile.jsonld # JSON-LD profile to translate the JSON response into JSON-LD
construct.sparql # optional SPARQL CONSTRUCT query to create triples that JSON-LD cannot create
service.php # optional script to perform specific actions
# (see 'services/advanced_examples/manual_config_example')
The config.ini file provides the following parameters:
Parameter | Mandatory/Optional | Description |
---|---|---|
custom_parameter | Mandatory | Array of arguments of the service to be passed as HTTP query string parameters. Has to be set but may be left empty when the service takes no parameter. |
api_query | Mandatory | The template of the Web API query string. It contains placeholders for the arguments defined in custom_parameter. |
cache_expires_after | Optional | Maximum time (in seconds) to cache responses from the Web API. Default: 2592000 = 30 days |
http_header | Optional | Array of HTTP headers sent along with the Web API query. Default: none |
add_provenance | Optional | Whether to add provenance information as part of the graph that is being produced. Values are true or false. Default: false. More details about produced provenance information can be found here. |
custom_parameter.pass_multiple_values_as_csv | Optional | Define how multiple values of a service argument are passed to the Web API: true = as a comma-separated value, false = value is split and Web API is invoked once for each value. Default: true |
Example:
custom_parameter[] = param1
custom_parameter[] = param2
custom_parameter.pass_multiple_values_as_csv[param2] = false
api_query = "https://example.org/api/service/?param1={param1}¶m2={param2}"
http_header[Authorization] = "token"
add_provenance = true
In this configuration method, the micro-service folder is organized as follows:
ServiceDescription.ttl # SPARQL Service Description describing this micro-service
ShapesGraph.ttl # optional SHACL description of the graphs produced by the service
profile.jsonld # JSON-LD profile to translate the JSON response into JSON-LD
construct.sparql # optional SPARQL CONSTRUCT query to create triples that JSON-LD cannot create
service.php # optional script to perform specific actions (see 'services/advanced_examples/manual_config_example')
The micro-service description is provided by an RDF graph following the SPARQL Service Description recommendation (SD). See provided examples for more details (conventionally named with extension '_sd'), e.g. flickr/getPhotosByTags_sd.
The SD graph in file ServiceDescription.ttl
is described in article 4.
In a nutshell, it describes a ressource that is an instance of sd:Service
and sms:Service
(namespace sms
stands for http://ns.inria.fr/sparql-micro-service#
) whose data source (dct:source
) is a Web API (schema:WebAPI
) that has a search action (schema:potentialAction
).
In turn, the search action defines the arguments expected by the service and how they are passed on the Web API query string.
Example. The example below is a the description graph of flickr/getPhotosByTags_sd.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
@prefix sd: <http://www.w3.org/ns/sparql-service-description#>.
@prefix frmt: <http://www.w3.org/ns/formats/>.
@prefix dct: <http://purl.org/dc/terms/>.
@prefix shacl: <http://www.w3.org/ns/shacl#>.
@prefix void: <http://rdfs.org/ns/void#>.
@prefix hydra: <http://www.w3.org/ns/hydra/core#>.
@prefix schema: <http://schema.org/>.
@prefix skos: <http://www.w3.org/2004/02/skos/core#>.
@prefix sms: <http://ns.inria.fr/sparql-micro-service#>.
@base <http://example.org/sparql-ms/flickr/getPhotosByTags_sd/>.
# This file is loaded as graph <ServiceDescription>
<>
a sd:Service, sms:Service;
sd:endpoint <>;
sd:supportedLanguage sd:SPARQL11Query;
sd:feature sd:BasicFederatedQuery, sd:EmptyGraphs;
sd:resultFormat frmt:SPARQL_Results_XML, frmt:SPARQL_Results_JSON, frmt:SPARQL_Results_CSV, frmt:SPARQL_Results_TSV,
frmt:RDF_XML, frmt:Turtle, frmt:JSON-LD, frmt:Trig;
schema:name "Search photos that match all of the given tags on Flickr";
schema:description '''This SPARQL micro-service searches photos on <a href="https://flickr.com" target="_new">Flickr</a>, that match all of the given tags. A maximum of 100 photos are returned.''';
sd:defaultDataset [
a sd:Dataset, void:Dataset;
sd:defaultGraph [ a sd:Graph; shacl:shapesGraph <ShapesGraph> ];
sd:namedGraph [ a sd:Graph; sd:name <ServiceDescription> ];
sd:namedGraph [ a sd:Graph; sd:name <ShapesGraph> ];
void:vocabulary <http://schema.org/>, <http://www.w3.org/ns/shacl#>, <http://www.w3.org/ns/hydra/core#>;
void:sparqlEndpoint <>;
];
schema:keywords "photography", "flickr", "photo", "picture", "snapshot";
schema:publisher [ a schema:Organization;
schema:name "Université Côte d'Azur, CNRS, Inria, I3S";
schema:logo
"http://univ-cotedazur.fr/fr/university/communication-presse/charte-et-logos/logo/png/uca-logo-large",
"https://iww.inria.fr/dircom/logoinria-eng.png",
"http://www.cnrs.fr/themes/custom/cnrs/logo.svg";
schema:contactPoint [ a schema:ContactPoint;
schema:contactType "technical support";
schema:name "Franck Michel";
schema:email "[email protected]";
schema:url <https://w3id.org/people/franckmichel>;
];
];
sms:exampleQuery '''
prefix schema: <http://schema.org/>
SELECT ?photo ?title ?img WHERE {
?photo a schema:Photograph;
schema:keywords "brooklyn", "bicycle";
schema:name ?title;
schema:contentUrl ?img.
}
''';
# 432000s = 5 days
sms:cacheExpiresAfter "P432000S"^^xsd:duration;
# Add provenance information to the graph generated at each invocation?
sms:addProvenance "false"^^xsd:boolean;
dct:source [
a schema:WebAPI; schema:name "Flickr API";
schema:url <https://www.flickr.com/services/api/>;
schema:potentialAction <APIService>;
];
.
# Web API service being wrapped by this µ-service + parameters binding
<APIService>
a schema:SearchAction;
schema:documentation "Each tag is provided as a value of property schema:keyowrds in the SPARQL graph pattern.";
a hydra:IriTemplate;
hydra:template "https://api.flickr.com/services/rest/?method=flickr.photos.search&format=json&nojsoncallback=1&api_key=<api_key>&tag_mode=all&sort=relevance&privacry_filter=1&extras=date_upload%2Cdate_taken%2Cowner_name%2Ctags&per_page=100&tags={tags}".
hydra:mapping [
hydra:variable "tags";
schema:description "Tags that retrieved photos must be associated with.";
hydra:required "true"^^xsd:boolean;
skos:example "bicycle";
# Use either hydra:property or shacl:sourceShape
hydra:property schema:keywords;
#shacl:sourceShape <ShapesGraph#NamePropertyShape>;
# How multiple values of a service custom argument are passed to the Web API:
# true = as a comma-separated value, false = value is split and Web API is invoked once for each value. Default: true
sms:passMultipleValuesAsCsv "true"^^xsd:boolean;
].
The service configuration parameters are expressed in the SD graph as follows:
Parameter or property | Mandatory/Optional | Description |
---|---|---|
dct:source |
Mandatory | An instance of schema:WebAPI that describes the Web API; its associated search action (schema:potentialAction ) describes the Web API query string template, the service arguments and optional HTTP headers. See below. |
Web API query string template | Mandatory | A hydra:IriTemplate (hydra:template ) providing the Web API query string template. It contains placeholders for the service's input arguments. |
Input arguments | Mandatory | Set of hydra:IriTemplateMapping resources (hydra:mapping ) associated with the Web API's potential action. Each argument comes with a name (hydra:variale ) mentioned in the template, and a mapping to a term of the input SPARQL query's graph pattern, along two methods: hydra:property simply gives the predicate to look for in the SPARQL graph pattern, while shacl:sourceShape points to the property shape that can help find the term in the graph pattern. |
HTTP headers | Optional | Property of the the Web API's potential action. An httpvoc:headers list whose elements are HTTP headers to be sent to the Web API. Each header consists of a httpvoc:fieldName , httpvoc:fieldValue and an optional httpvoc:hdrName . See the HTTP Vocabulary in RDF 1.0. A usage example is provided in eol/getTraitsByTaxon_sd. |
sms:cacheExpiresAfter |
Optional | Property of the sd:Service instance. Maximum time (in seconds) to cache responses from the Web API. Default: "P2592000S"^^xsd:duration = 30 days |
sms:exampleQuery |
Optional | Property of the sd:Service instance. A typical SPARQL query that can be submitted to the service. Used to generate the test interface on the Web page. |
sms:exampleURI |
Optional | Property of the sd:Service instance. A URI that can be dereferenced using this service. Used to generate the test interface on the Web page. |
sms:addProvenance |
Optional | Property of the sd:Service instance. Whether to add provenance information as part of the graph that is being produced. Values are "true"^^xsd:boolean or "false"^^xsd:boolean . Default is false |
sms:passMultipleValuesAsCsv |
Optional | Property of a hydra:IriTemplateMapping resource (hydra:mapping ). Defines how multiple values of a service argument are passed to the Web API: "true"^^xsd:boolean = as a comma-separated value, "false"^^xsd:boolean = value is split and Web API is invoked once for each value. Default: true |
Since the service description graph is public (it can be queried and dereferenced), it is not suitable to keep sensitive information such as an API private key or security token.
Therefore, a companion file ServiceDescriptionPrivate.ttl
may be defined, loaded into as separate named graph that is not made public.
Both ServiceDescription.ttl
and ServiceDescriptionPrivate.ttl
do state facts about the same service, so that triples can be asserted in one or the other. The service will always work the same, only the public description will vary.
An example is provided in service flickr/getPhotosByTags_sd.
The service description graph can optionally be accompanied by a SHACL shapes graph that specifies the type of graph that the SPARQL micro-service is designed to produce. An example is provided in service flickr/getPhotosByTags_sd.
In certain situations, it may be necessary to re-inject the service arguments into the graph being produced by the service, so that this graph matches the query graph pattern. This is even mandatory when passing the arguments in client's SPARQL query.
Example. Consider a service whose arguments are passed in the the SPARQL query. The service expects a argument tag
provided with predicate schema:keywords
. In the SPARQL graph pattern below, "sunset" is the value of the tag
argument.
?photo
rdf:type schema:Photograph;
schema:keywords "sunset".
schema:url ?url.
To match this query, the service must not only generate triples with the rdf:type
and schema:url
predicates, but also the triple with the keyword "sunset" that was used to pass the argument. This is achieved using a placeholder in the construct.sparql
file.
In the example below, the tag
argument (whose value is "sunset" in the query) is 're-injected' in the graph using placeholder {tag}
:
CONSTRUCT {
<http://example.org/photo/{urlencode(tag)}>
a schema:Photograph;
schema:keywords {tag};
...
Do not add the double-quotes, they will be added automatically.
The {tag}
placeholder is replaced with "sunset"
.
If more than one value were provided, the placeholder will be replaced by the list of comma-separated, double-quoted values, e.g.: "sunset", "sea"
.
In case the argument is used to build a URI, the placeholder can contain the urlencode
keyword to escape special characters, as illustrated above in <http://example.org/photo/{urlencode(tag)}>
.
Translating the Web API JSON response into an RDF graph is carried out in two steps:
- Apply a JSON-LD 1.0 profile to the response;
- Optionnally, when mappings are needed that JSON-LD cannot express, a SPARQL CONSTRUCT query enriches the graph (file
construct.sparql
).
The most simple JSON-LD profile is depicted below. It creates ad-hoc terms in the http://ns.inria.fr/sparql-micro-service/api#
namespace for each property of the JSON response.
{ "@context": {
"@base": "http://ns.inria.fr/sparql-micro-service/item/",
"@vocab": "http://ns.inria.fr/sparql-micro-service/api#",
}}
This is a handy way of turning the Web API JSON response into RDF, and this allows manipulating the Web API response in a SPARQL query using the construct.sparql
file.
Note that many well-known namespaces are already declared when executing your CONSTRUCT query (those defined in the EasyRDF library), in addition to the ones in the global config.ini file.
A service argument may be given multiple values, using either HTTP query string parameters or terms of the SPARQL query graph pattern.
In the SPARQL query graph pattern, the values are simply passed as multiple values of a predicate, example:
?photo
a schema:Photograph;
schema:keywords "keyword1", "keyword2".
schema:url ?url.
Using HTTP query string parameters, the values are provided as a CSV value, example:
https://example.org/micro/service/?keyword=keyword1,keyword2
By default, the SPARQL micro-service will pass the argument to the Web API as a comma-separated list of the multiple values, example:
https://webapi.org/service/?tags=keyword1,keyword2
However, it is possible to instruct the a SPARQL micro-service to pass the values one at a time, thus entailing multiple invocations:
https://webapi.org/service/?tags=keyword1
https://webapi.org/service/?tags=keyword2
The graph finally generated by the SPARQL micro-service is the sum of all the graphs generated for each value.
This is achieved using either the custom_parameter.pass_multiple_values_as_csv
or sms:passMultipleValuesAsCsv
configuration parameters.