I have now written a follow-up to this post here
I want to make RDF data more developer-friendly. When you show a typical developer RDF, where they have previously been used to simple JSON or XML structures, they find the format confusing, and hard to code with. This is primarily because the data is a graph, and graphs don’t fit well with the tree structures of JSON and XML.
I have seen this problem tackled through the use of libraries that can parse and interpret the graph data, and present an easier interface to the developer. Whilst these have been useful, I still think there are some fundamental problems. JSON-LD also offers a solution to this problem, but is not sufficiently lightweight for environments where data structures change and develop regularly. I compare my approach with JSON-LD at the end of the post.
The problems described below are based on a particular problem I am trying to solve: I want to build developer-friendly APIs over data modelled as RDF, and obtained using SPARQL CONSTRUCT queries.
The problems fall into two categories of API call:
- Give me information about X (one thing)
- Give me information about all X1, X2, etc.. where all meets a certain condition (list)
Problems with a graph representing one thing
Problem: I don’t know what X is
If I call an API to find out about X, and get back the following RDF:
<uri:x> foaf:name "Bob Smith" .
Then it’s obvious what X is.
If I get this RDF back:
<uri:maybeX> foaf:name "Bob Smith" .
<uri:alsoMaybeX> foaf:name "Jane Smith" .
<uri:maybeX> foaf:knows <uri:alsoMaybeX> .
In this example, I have no idea what X is. This problem is usually solved using a heuristic, such as “the only resource of type T”. But these heuristics can be brittle, and changes to API data could easily break the heuristic.
I proposal to use a tree ontology to indicate the intention overall subject of the tree:
tree:tree tree:root <uri:x> .
Problems with a graph representing a list
Problem: ordering cannot easily expressed
If I call an API to get a list of things, then there is no commonly understood way to indicate the order of those things. The problem with general approaches to ordering in RDF, is that they don’t clearly indicate that the list specifically refers to the ordering of the API response. An API response is typically a dynamic ordering based on the current data, rather than an intrinsic ordering such as the ordering of events. An example would be “Page 4 of all Team GB athletes, ordered by surname, then first name”. In this example, the ordering is dynamic, and only known after the query data has been returned.
I propose to use a tree ontology to indicate a list of nodes in the graph that represent the API results. For example:
tree:tree tree:page "4"^^xsd:int .
tree:tree tree:first <uri:a> .
<uri:a> tree:next <uri:b> .
<uri:b> tree:next <uri:c> .
<uri:a> foaf:name "Person 1 in list" .
<uri:b> foaf:name "Person 2 in list" .
<uri:c> foaf:name "Person 3 in list" .
The additional tree ontology data above can be easily inserted into API responses by adding additional triples to the top of a SPARQL CONSTRUCT query.
Using RDF Tree ontology to build developer friendly data
Using the information from the tree ontology, it is possible to build developer friendly serialisations of the RDF data that are more directly usable for typical use-cases such as building tabular HTML or other visual representations of the data.
Building the RDF Tree from an RDF graph
The RDF tree is built by starting at the root (or multiple roots for lists) and traversing the graph until a rule causes the traversal to halt. The graph is traversed, breadth-first, following predicates in both directions. I used the following three halting rules, which seems to make effective trees for the use-cases I have looked at:
- If a parent node is present in the tree with the same resource as one traversed to, halt the traversal
- Do not follow the rdf:type property in the inverse direction
- If a list item resource is defined with the same resource as one traversed to, halt the traversal after one additional level in the tree
The following two examples show JSON RDF Tree serialisations of Olympics data, applying the rules above. The original Turtle data is shown, along with the resultant, proposed RDF Tree serialisation. The ‘^’ symbol is used to represent triples followed in the inverse direction of the predicate.
One athlete as RDF Turtle
@prefix par: <http://purl.org/vocab/participation/schema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix geo: <http://www.bbc.co.uk/ontologies/geopolitical/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix domain: <http://www.bbc.co.uk/ontologies/domain/> .
@prefix oly: <http://www.bbc.co.uk/ontologies/2012olympics/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix sport: <http://www.bbc.co.uk/ontologies/sport/> .
@prefix tree: <http://purl.org/rdf-tree/> .
tree:tree tree:start <http://www.bbc.co.uk/things/4e40ce40-b632-4a42-98d7-cf97067f7bf9#id> .
<http://www.bbc.co.uk/things/7ef7ffdf-f101-4470-adc0-38a5abac9122#id> a sport:CompetitiveSportingOrganisation ;
oly:territory <http://www.bbc.co.uk/things/territories/gb#id> ;
domain:document <http://www.bbc.co.uk/sport/olympics/2012/countries/great-britain> ;
domain:shortName "Great Britain & N. Ireland"^^xsd:string ;
domain:name "Team GB"^^xsd:string .
<http://www.bbc.co.uk/things/4e40ce40-b632-4a42-98d7-cf97067f7bf9#id> a sport:Person ;
par:role_at <http://www.bbc.co.uk/things/7ef7ffdf-f101-4470-adc0-38a5abac9122#id> ;
oly:dateOfBirth "1976-10-24"^^xsd:date ;
oly:gender "M"^^xsd:string ;
oly:height "172.0"^^xsd:float ;
oly:weight "72.0"^^xsd:float ;
domain:name "Ben Ainslie"^^xsd:string ;
sport:competesIn <http://www.bbc.co.uk/things/2012/sam002#id>, <http://www.bbc.co.uk/things/2012/sam005#id> ;
sport:discipline <http://www.bbc.co.uk/things/d65c5dce-f5e4-4340-931b-16ca1848d092#id> ;
domain:document <http://www.bbc.co.uk/sport/olympics/2012/athletes/4e40ce40-b632-4a42-98d7-cf97067f7bf9>, <http://www.facebook.com/pages/Ben-Ainslie/108182689201922> ;
foaf:familyName "Ainslie"^^xsd:string ;
foaf:givenName "Ben"^^xsd:string .
<http://www.facebook.com/pages/Ben-Ainslie/108182689201922> a domain:Document ;
domain:documentType <http://www.bbc.co.uk/things/document-types/external> , <http://www.bbc.co.uk/things/document-types/facebook> .
<http://www.bbc.co.uk/sport/olympics/2012/athletes/4e40ce40-b632-4a42-98d7-cf97067f7bf9> a domain:Document ;
domain:domain <http://www.bbc.co.uk/things/domains/olympics2012> ;
domain:documentType <http://www.bbc.co.uk/things/document-types/bbc-document> .
<http://www.bbc.co.uk/things/2012/sam002#id> a sport:MedalCompetition ;
domain:name "Sailing - Men's Finn"^^xsd:string ;
domain:shortName "Men's Finn"^^xsd:string ;
domain:externalId <urn:ioc2012:SAM002000> ;
domain:document <http://www.bbc.co.uk/sport/olympics/2012/sports/sailing/events/mens-finn> .
<http://www.bbc.co.uk/things/2012/sam005#id> a sport:MedalCompetition ;
domain:name "Sailing - Men's 470"^^xsd:string ;
domain:shortName "Men's 470"^^xsd:string ;
domain:externalId <urn:ioc2012:SAM005000> ;
domain:document <http://www.bbc.co.uk/sport/olympics/2012/sports/sailing/events/mens-470> .
<http://www.bbc.co.uk/things/d65c5dce-f5e4-4340-931b-16ca1848d092#id> a sport:SportsDiscipline ;
domain:document <http://www.bbc.co.uk/sport/olympics/2012/sports/sailing> ;
domain:name "Sailing"^^xsd:string .
<http://www.bbc.co.uk/things/territories/gb#id> a geo:Territory ;
domain:name "the United Kingdom of Great Britain and Northern Ireland"^^xsd:string ;
geo:isInGroup <http://www.bbc.co.uk/things/81b14df8-f9d2-4dff-a676-43a1a9a5c0a5#id> .
<http://www.bbc.co.uk/things/81b14df8-f9d2-4dff-a676-43a1a9a5c0a5#id> a geo:Group ;
domain:name "Europe"^^xsd:string ;
geo:groupType <http://www.bbc.co.uk/things/group-types/bbc-news-geo-regions> .
One athlete RDF Tree JSON
{
"rdf:about": "http://www.bbc.co.uk/things/4e40ce40-b632-4a42-98d7-cf97067f7bf9#id",
"domain:name": "Ben Ainslie",
"foaf:familyName": "Ainslie",
"foaf:givenName": "Ben",
"oly:dateOfBirth": "1976-10-24",
"oly:gender": "M",
"oly:height": "172.0",
"oly:weight": "72.0",
"domain:document": [
{
"rdf:about": "http://www.facebook.com/pages/Ben-Ainslie/108182689201922",
"domain:documentType": [
{
"rdf:about": "http://www.bbc.co.uk/things/document-types/facebook"
},
{
"rdf:about": "http://www.bbc.co.uk/things/document-types/external"
}
],
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/domain/Document"
}
},
{
"rdf:about": "http://www.bbc.co.uk/sport/olympics/2012/athletes/4e40ce40-b632-4a42-98d7-cf97067f7bf9",
"domain:documentType": {
"rdf:about": "http://www.bbc.co.uk/things/document-types/bbc-document"
},
"domain:domain": {
"rdf:about": "http://www.bbc.co.uk/things/domains/olympics2012"
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/domain/Document"
}
}
],
"par:role_at": {
"rdf:about": "http://www.bbc.co.uk/things/7ef7ffdf-f101-4470-adc0-38a5abac9122#id",
"domain:name": "Team GB",
"domain:shortName": "Great Britain \u0026 N. Ireland",
"domain:document": {
"rdf:about": "http://www.bbc.co.uk/sport/olympics/2012/countries/great-britain"
},
"oly:territory": {
"rdf:about": "http://www.bbc.co.uk/things/territories/gb#id",
"domain:name": "the United Kingdom of Great Britain and Northern Ireland",
"geo:isInGroup": {
"rdf:about": "http://www.bbc.co.uk/things/81b14df8-f9d2-4dff-a676-43a1a9a5c0a5#id",
"domain:name": "Europe",
"geo:groupType": {
"rdf:about": "http://www.bbc.co.uk/things/group-types/bbc-news-geo-regions"
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/geopolitical/Group"
}
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/geopolitical/Territory"
}
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/sport/CompetitiveSportingOrganisation"
}
},
"sport:competesIn": [
{
"rdf:about": "http://www.bbc.co.uk/things/2012/sam002#id",
"domain:name": "Sailing - Men\u0027s Finn",
"domain:shortName": "Men\u0027s Finn",
"domain:document": {
"rdf:about": "http://www.bbc.co.uk/sport/olympics/2012/sports/sailing/events/mens-finn"
},
"domain:externalId": {
"rdf:about": "urn:ioc2012:SAM002000"
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/sport/MedalCompetition"
}
},
{
"rdf:about": "http://www.bbc.co.uk/things/2012/sam005#id",
"domain:name": "Sailing - Men\u0027s 470",
"domain:shortName": "Men\u0027s 470",
"domain:document": {
"rdf:about": "http://www.bbc.co.uk/sport/olympics/2012/sports/sailing/events/mens-470"
},
"domain:externalId": {
"rdf:about": "urn:ioc2012:SAM005000"
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/sport/MedalCompetition"
}
}
],
"sport:discipline": {
"rdf:about": "http://www.bbc.co.uk/things/d65c5dce-f5e4-4340-931b-16ca1848d092#id",
"domain:name": "Sailing",
"domain:document": {
"rdf:about": "http://www.bbc.co.uk/sport/olympics/2012/sports/sailing"
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/sport/SportsDiscipline"
}
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/sport/Person"
}
}
List of three athletes as RDF Turtle
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix par: <http://purl.org/vocab/participation/schema#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix domain: <http://www.bbc.co.uk/ontologies/domain/> .
@prefix sport: <http://www.bbc.co.uk/ontologies/sport/> .
@prefix oly: <http://www.bbc.co.uk/ontologies/2012olympics/> .
@prefix geo-pol: <http://www.bbc.co.uk/ontologies/geopolitical/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix tree: <http://purl.org/rdf-tree/> .
tree:tree tree:first <http://www.bbc.co.uk/things/4e40ce40-b632-4a42-98d7-cf97067f7bf9#id> .
<http://www.bbc.co.uk/things/4e40ce40-b632-4a42-98d7-cf97067f7bf9#id> tree:next <http://www.bbc.co.uk/things/f2798806-4e54-47ff-a1ec-32beefde2058#id> .
<http://www.bbc.co.uk/things/f2798806-4e54-47ff-a1ec-32beefde2058#id> tree:next <http://www.bbc.co.uk/things/82f5db84-0591-49ee-b6f4-a1d26e9381fb#id> .
<http://www.bbc.co.uk/things/4e40ce40-b632-4a42-98d7-cf97067f7bf9#id> a sport:Person ;
oly:isMedallistFor <http://www.bbc.co.uk/things/3143ecc6-ffa4-4446-9d13-ee60801c4881#id> ;
domain:name "Ben Ainslie"^^xsd:string ;
domain:canonicalName "Ben Ainslie"^^xsd:string ;
foaf:givenName "Ben"^^xsd:string ;
foaf:familyName "Ainslie"^^xsd:string ;
oly:gender "M"^^xsd:string ;
sport:discipline <http://www.bbc.co.uk/things/d65c5dce-f5e4-4340-931b-16ca1848d092#id> ;
domain:document <http://www.bbc.co.uk/sport/olympics/2012/athletes/4e40ce40-b632-4a42-98d7-cf97067f7bf9> .
<http://www.bbc.co.uk/things/d65c5dce-f5e4-4340-931b-16ca1848d092#id> a sport:SportsDiscipline ;
domain:name "Sailing"^^xsd:string ;
domain:document <http://www.bbc.co.uk/sport/olympics/2012/sports/sailing> .
_:node166n6c6vlx37 a sport:CompetesForRole ;
par:holder <http://www.bbc.co.uk/things/4e40ce40-b632-4a42-98d7-cf97067f7bf9#id> ;
par:role_at <http://www.bbc.co.uk/things/7ef7ffdf-f101-4470-adc0-38a5abac9122#id> .
<http://www.bbc.co.uk/things/7ef7ffdf-f101-4470-adc0-38a5abac9122#id> a sport:CompetitiveSportingOrganisation ;
domain:name "Team GB"^^xsd:string ;
domain:shortName "Great Britain & N. Ireland"^^xsd:string ;
domain:document <http://www.bbc.co.uk/sport/olympics/2012/countries/great-britain> .
<http://www.bbc.co.uk/things/8d6ae957-d338-442b-99d7-190f20b78dd4#id> oly:oneToWatch <http://www.bbc.co.uk/things/4e40ce40-b632-4a42-98d7-cf97067f7bf9#id> .
<http://www.bbc.co.uk/things/82f5db84-0591-49ee-b6f4-a1d26e9381fb#id> a sport:Person ;
domain:name "Usain Bolt"^^xsd:string ;
domain:canonicalName "Usain Bolt"^^xsd:string ;
foaf:givenName "Usain"^^xsd:string ;
foaf:familyName "Bolt"^^xsd:string ;
oly:gender "M"^^xsd:string ;
oly:worldOlympicDream "true"^^xsd:boolean ;
sport:discipline <http://www.bbc.co.uk/things/b3a086df-ab42-2b44-be8b-76b600bfcdce#id> ;
domain:document <http://www.bbc.co.uk/sport/olympics/2012/athletes/82f5db84-0591-49ee-b6f4-a1d26e9381fb> .
<http://www.bbc.co.uk/things/b3a086df-ab42-2b44-be8b-76b600bfcdce#id> a sport:SportsDiscipline ;
domain:name "Athletics"^^xsd:string ;
domain:document <http://www.bbc.co.uk/sport/olympics/2012/sports/athletics> .
_:node166n6c6vlx113 a sport:CompetesForRole ;
par:holder <http://www.bbc.co.uk/things/82f5db84-0591-49ee-b6f4-a1d26e9381fb#id> ;
par:role_at <http://www.bbc.co.uk/things/76369f3b-65a0-4e69-8c52-859adfdefa49#id> .
<http://www.bbc.co.uk/things/76369f3b-65a0-4e69-8c52-859adfdefa49#id> a sport:CompetitiveSportingOrganisation ;
domain:name "Jamaica"^^xsd:string ;
domain:shortName "Jamaica"^^xsd:string ;
domain:externalId <urn:ioc2012:jam> ;
domain:document <http://www.bbc.co.uk/sport/olympics/2012/countries/jamaica> .
<http://www.bbc.co.uk/things/f2798806-4e54-47ff-a1ec-32beefde2058#id> a sport:Person ;
oly:isMedallistFor <http://www.bbc.co.uk/things/3143ecc6-ffa4-4446-9d13-ee60801c4881#id> ;
domain:name "Majlinda Kelmendi"^^xsd:string ;
domain:canonicalName "Majlinda Kelmendi"^^xsd:string ;
foaf:givenName "Majlinda"^^xsd:string ;
foaf:familyName "Kelmendi"^^xsd:string ;
oly:gender "W"^^xsd:string ;
sport:discipline <http://www.bbc.co.uk/things/654f550c-0c2d-2341-a8f5-66e3a9ba28ba#id> ;
domain:document <http://www.bbc.co.uk/sport/olympics/2012/athletes/f2798806-4e54-47ff-a1ec-32beefde2058> .
<http://www.bbc.co.uk/things/654f550c-0c2d-2341-a8f5-66e3a9ba28ba#id> a sport:SportsDiscipline ;
domain:name "Judo"^^xsd:string ;
domain:document <http://www.bbc.co.uk/sport/olympics/2012/sports/judo> .
_:node166n6c6vlx445 a sport:CompetesForRole ;
par:holder <http://www.bbc.co.uk/things/f2798806-4e54-47ff-a1ec-32beefde2058#id> ;
par:role_at <http://www.bbc.co.uk/things/7ef7ffdf-f101-4470-adc0-38a5abac9122#id> .
List of three athletes RDF Tree JSON
Note the repeating country nodes: these are useful for tabular representations.
[
{
"rdf:about": "http://www.bbc.co.uk/things/4e40ce40-b632-4a42-98d7-cf97067f7bf9#id",
"domain:canonicalName": "Ben Ainslie",
"domain:name": "Ben Ainslie",
"foaf:familyName": "Ainslie",
"foaf:givenName": "Ben",
"oly:gender": "M",
"^oly:oneToWatch": {
"rdf:about": "http://www.bbc.co.uk/things/8d6ae957-d338-442b-99d7-190f20b78dd4#id"
},
"^par:holder": {
"par:role_at": {
"rdf:about": "http://www.bbc.co.uk/things/7ef7ffdf-f101-4470-adc0-38a5abac9122#id",
"domain:name": "Team GB",
"domain:shortName": "Great Britain \u0026 N. Ireland",
"^par:role_at": {
"par:holder": {
"rdf:about": "http://www.bbc.co.uk/things/f2798806-4e54-47ff-a1ec-32beefde2058#id"
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/sport/CompetesForRole"
}
},
"domain:document": {
"rdf:about": "http://www.bbc.co.uk/sport/olympics/2012/countries/great-britain"
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/sport/CompetitiveSportingOrganisation"
}
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/sport/CompetesForRole"
}
},
"domain:document": {
"rdf:about": "http://www.bbc.co.uk/sport/olympics/2012/athletes/4e40ce40-b632-4a42-98d7-cf97067f7bf9"
},
"oly:isMedallistFor": {
"rdf:about": "http://www.bbc.co.uk/things/3143ecc6-ffa4-4446-9d13-ee60801c4881#id",
"^oly:isMedallistFor": {
"rdf:about": "http://www.bbc.co.uk/things/f2798806-4e54-47ff-a1ec-32beefde2058#id"
}
},
"sport:discipline": {
"rdf:about": "http://www.bbc.co.uk/things/d65c5dce-f5e4-4340-931b-16ca1848d092#id",
"domain:name": "Sailing",
"domain:document": {
"rdf:about": "http://www.bbc.co.uk/sport/olympics/2012/sports/sailing"
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/sport/SportsDiscipline"
}
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/sport/Person"
}
},
{
"rdf:about": "http://www.bbc.co.uk/things/f2798806-4e54-47ff-a1ec-32beefde2058#id",
"domain:canonicalName": "Majlinda Kelmendi",
"domain:name": "Majlinda Kelmendi",
"foaf:familyName": "Kelmendi",
"foaf:givenName": "Majlinda",
"oly:gender": "W",
"^par:holder": {
"par:role_at": {
"rdf:about": "http://www.bbc.co.uk/things/7ef7ffdf-f101-4470-adc0-38a5abac9122#id",
"domain:name": "Team GB",
"domain:shortName": "Great Britain \u0026 N. Ireland",
"^par:role_at": {
"par:holder": {
"rdf:about": "http://www.bbc.co.uk/things/4e40ce40-b632-4a42-98d7-cf97067f7bf9#id"
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/sport/CompetesForRole"
}
},
"domain:document": {
"rdf:about": "http://www.bbc.co.uk/sport/olympics/2012/countries/great-britain"
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/sport/CompetitiveSportingOrganisation"
}
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/sport/CompetesForRole"
}
},
"domain:document": {
"rdf:about": "http://www.bbc.co.uk/sport/olympics/2012/athletes/f2798806-4e54-47ff-a1ec-32beefde2058"
},
"oly:isMedallistFor": {
"rdf:about": "http://www.bbc.co.uk/things/3143ecc6-ffa4-4446-9d13-ee60801c4881#id",
"^oly:isMedallistFor": {
"rdf:about": "http://www.bbc.co.uk/things/4e40ce40-b632-4a42-98d7-cf97067f7bf9#id"
}
},
"sport:discipline": {
"rdf:about": "http://www.bbc.co.uk/things/654f550c-0c2d-2341-a8f5-66e3a9ba28ba#id",
"domain:name": "Judo",
"domain:document": {
"rdf:about": "http://www.bbc.co.uk/sport/olympics/2012/sports/judo"
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/sport/SportsDiscipline"
}
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/sport/Person"
}
},
{
"rdf:about": "http://www.bbc.co.uk/things/82f5db84-0591-49ee-b6f4-a1d26e9381fb#id",
"domain:canonicalName": "Usain Bolt",
"domain:name": "Usain Bolt",
"foaf:familyName": "Bolt",
"foaf:givenName": "Usain",
"oly:gender": "M",
"oly:worldOlympicDream": "true",
"^par:holder": {
"par:role_at": {
"rdf:about": "http://www.bbc.co.uk/things/76369f3b-65a0-4e69-8c52-859adfdefa49#id",
"domain:name": "Jamaica",
"domain:shortName": "Jamaica",
"domain:document": {
"rdf:about": "http://www.bbc.co.uk/sport/olympics/2012/countries/jamaica"
},
"domain:externalId": {
"rdf:about": "urn:ioc2012:jam"
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/sport/CompetitiveSportingOrganisation"
}
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/sport/CompetesForRole"
}
},
"domain:document": {
"rdf:about": "http://www.bbc.co.uk/sport/olympics/2012/athletes/82f5db84-0591-49ee-b6f4-a1d26e9381fb"
},
"sport:discipline": {
"rdf:about": "http://www.bbc.co.uk/things/b3a086df-ab42-2b44-be8b-76b600bfcdce#id",
"domain:name": "Athletics",
"domain:document": {
"rdf:about": "http://www.bbc.co.uk/sport/olympics/2012/sports/athletics"
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/sport/SportsDiscipline"
}
},
"rdf:type": {
"rdf:about": "http://www.bbc.co.uk/ontologies/sport/Person"
}
}
]
Syntax and feedback
I have written a library to perform RDF to RDF Tree conversion, and I am looking for feedback on the syntax and general approach before I finalise the details.
The design of RDF Tree is intended to be lossless, from an information perspective, but to maximise practical use by developers.
Comparison to JSON LD
This approach above is a lightweight alternative to JSON LD. The framing approached used by JSON LD to assure consistent and predictable access to data is replaced with a more dynamic approach where the tree root is defined by the RDF API response. I have identified following differences to JSON LD:
- RDF Tree is focused on developer simplicity: this includes the creators and consumers of APIs. An example of this would be the decision to continue to use prefixes for predicates. This makes the data easy to produce, and avoid the complexities of ‘contextualisation’ of shorter predicate names.
- RDF Tree is not intended to be re-used as RDF data. APIs that produce RDF Tree would need to also produce RDF. Those interested in tree-like or tabular data would use RDF Tree, those interested in the graph data would use the RDF.
- As the ontology structures and SPARQL queries change, little or no maintenance is required to continue to support predictable response data.
- Any tree structured data can be produced (XML can be built from the same abstract tree)