1Ghent University – imec – IDLab, Belgium
2Department of Computer and Information Science (IDA) — Linköping University, Sweden
Querying over multiple GraphQL interfaces is hard with the current solutions:
Stitch multiple schemas together, forward subqueries to other interfaces
Like delegation, with improved spreading of types over different interfaces
Support for federation is built into its foundations.
Instead of interface-specific ID
s.
Instead of interface-specific schemas.
GraphQL is highly popular and widely used.
→ Querying RDF with GraphQL would be highly beneficial.
GraphQL interface wrapper around RDF sources
Graph store with GraphQL interface via (SHACL) shape definitions
SPARQL engine, with conversion of GraphQL to SPARQL
Engine-independent GraphQL to SPARQL converter with JSON-LD contexts
config.json
: interface parameters and available services (SPARQL, RDF files,...)
{ "name": "dbpedia-sparql-hgql-demo", "schema": "schema.graphql", "server": { "port": 8080, "graphql": "/graphql", "graphiql": "/graphiql" }, "services": [{ "id": "dbpedia-sparql", "type": "SPARQLEndpointService", "url": "http://dbpedia.org/sparql/", "graph": "http://dbpedia.org" }] }
__Context
maps fields to IRIs
@service
defines source for a type/field
type __Context { Person: _@href(iri: "http://dbpedia.org/ontology/Person") City: _@href(iri: "http://dbpedia.org/ontology/City") name: _@href(iri: "http://xmlns.com/foaf/0.1/name") label: _@href(iri: "http://www.w3.org/2000/01/rdf-schema#label") } type Person @service(id:"dbpedia-sparql") { name: String @service(id:"dbpedia-sparql") label: [String] @service(id:"dbpedia-sparql") birthPlace: City @service(id:"dbpedia-sparql") birthDate: String @service(id:"dbpedia-sparql") }
Both valid GraphQL response and RDF
{ "data": { "Person_GET": [ { "_id": "http://dbpedia.org/resource/Sani_ol_molk", "_type": "http://dbpedia.org/ontology/Person", "name": "Mirza Abolhassan Khan Ghaffari" } ], "@context": { "_id": "@id", "_type": "@type", "name": "http://xmlns.com/foaf/0.1/name" } } }
schema { query: RootRDFQuery } type RootRDFQuery { humans (...): [Human] } type Human { uri: ID! label: String! id (...): ID! name (...): String! friends (...): [Human] }
...
: auto-generated filters, aggregators, ...
Enhanced GraphQL functionality: filtering, ordering, transformation
{ humans (where: {name:{pattern:"^L"}}, orderBy: name) { id name height (transform: "$height / 0.3048") friends { id name } } }
@schema
query var)GraphQL:
{ Human { name height } }
SPARQL:
SELECT ?name ?height WHERE { _:b1 a :Human; :name ?name; :height ?height. }
Prefixes:
query withPrefixes @prefix(foaf: "http://xmlns.com/foaf/0.1/") { Human { foaf:name } }
Aliases:
query withAliases @config(alias: {myType: "http://ex.com/my-type", myProp: "http://ex.com/my-prop"}) { myType { myProp } }
@id
@reverse
@language
@type
GraphQL:
{ label artist { label } }
JSON-LD context:
{ "label": "http://www.w3.org/2000/01/rdf-schema#label", "artist": "http://dbpedia.org/ontology/musicalArtist" }
SPARQL:
SELECT ?label ?writer ?artist_label WHERE { _:b1 rdfs:label ?label; dbo:writer ?writer. _:b1 dbo:musicalArtist [ rdfs:label ?artist_label ]. }
Name | Open-source | Engine-independent | Lifting method |
---|---|---|---|
HyperGraphQL | ✓ | ✓ | GraphQL schema |
TopBraid | ✕ | ✕ | Shapes / GraphQL schema |
Stardog | ✕ | ✕ | Namespaces / GraphQL schema |
GraphQL-LD | ✓ | ✓ | JSON-LD context |
Because queries and schemas have no global semantics
Federated querying is a well-established domain in the Semantic Web
Multiple approaches exist: HyperGraphQL, TopBraid, Stardog, GraphQL-LD
Future standardization may be required for aligning approaches