1. Decentralized knowledge graphs are great sources of data, but so is aggregated data. There is a case to be made for both.
more
2. Access to data requires authentication (often across different domains). The solution usually puts the burden on the user.
3. Documents may contain data that is not useful (i.e. how do I just get the name and picture?).
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
<>
a <http://xmlns.com/foaf/0.1/PersonalProfileDocument> ;
<http://xmlns.com/foaf/0.1/primaryTopic> <#me> .
<#me>
a <http://xmlns.com/foaf/0.1/Person> ;
<http://www.w3.org/ns/auth/cert#key> <#keyone> ;
<http://www.w3.org/ns/pim/space#preferencesFile> <Preferences/prefs> ;
<http://www.w3.org/ns/pim/space#storage> <.> ;
<http://www.w3.org/ns/solid/terms#inbox> <inbox/> ;
<http://www.w3.org/ns/solid/terms#privateTypeIndex> <privIndex.ttl> ;
<http://www.w3.org/ns/solid/terms#publicTypeIndex> <publicTypeIndex.ttl> ;
<http://xmlns.com/foaf/0.1/img> <avatar.jpg> ;
<http://xmlns.com/foaf/0.1/mbox> <mailto:andrei@fcns.eu>, <mailto:andrei@w3.org> ;
<http://xmlns.com/foaf/0.1/name> "Andrei Vlad Sambra" ;
<http://xmlns.com/foaf/0.1/nick> "Deiu" ;
........
4. Fetching from multiple locations can go wrong on different fronts
Designed for querying a single data store
Designed to query through dedicated endpoints
There are efforts to federate SPARQL queries, but you usually need to know the endpoints ahead of time
Link-following SPARQL has been proposed as an improvement to SPARQL, but it hasn't been fully implemented/supported and the response would still be flat (apps require additional logic to map the data to the UI)
1. Developers want tools that match how they think about UI. For this reason, twinql allows you to specify the shape of the data to match the UI.
@prefix foaf http://xmlns.com/foaf/0.1/
https://bob.me/profile#me {
foaf.name
foaf.knows {
foaf.name
foaf.image
}
}
{
"@context": {
"foaf": "http://xmlns.com/foaf/0.1/"
},
"@id": "https://bob.me/profile#me",
"foaf:name": [
"Bob"
],
"foaf:knows": [
{
"@id": "https://alice.me/card#me",
"foaf:name": [
"Alice"
],
"foaf:img": [
"https://alice.me/avatar.jpg"
]
.....
more
2. As opposed to SPARQL, data comes from individual requests to the resources' own URIs. Yes, this means you can even query over a bunch of static documents! Take Tim Berner-Lee's static FOAF document for example:
@prefix rdf http://www.w3.org/1999/02/22-rdf-syntax-ns#
@prefix dc http://purl.org/dc/elements/1.1/
https://www.w3.org/People/Berners-Lee/card {
dc.title
rdf.type
}
{
"@context": {
"rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
"dc": "http://purl.org/dc/elements/1.1/"
},
"@id": "https://www.w3.org/People/Berners-Lee/card",
"dc:title": [
"Tim Berners-Lee's FOAF file"
],
"rdf:type": [
"http://xmlns.com/foaf/0.1/PersonalProfileDocument"
]
}
Results in:
2. Cross-domain auth is hard. Don't overwhelm the user with too much UI. Delegate!
Any auth
Delegation*
* WebID-TLS delegation
Device
Server (with agent)
The Web
3. Asking for data right now is incredibly imperative (hundreds of lines of code).
Given a data model three levels deep and with a branch factor of B:
1. Ask for the original thing
Handle error
2. Ask for next things
Handle each error
3. For each of those ask for next things
Handle each error
There are B * D network requests/errors to deal with at the HTTP level alone.
Example of imperative programming using Solid-Client
(no room to even show the result)
// Display name and picture for a person
var webid = 'https://bob.me/profile#me'
solid.web.get(webid).then(function(response) {
var graph = response.parsedGraph()
var subject = $rdf.sym(response.url)
// get name
var obj = graph.any(subject, vocab.foaf('name'))
if (obj) {
name = obj.value
}
// get picture
obj = graph.any(subject, vocab.foaf('img'))
if (obj) {
pic = obj.value
}
// Do something in the UI with the name and picture
}).catch(function(err) {
// do something with the HTTP error
console.log(err)
})
Same data requested, this time using twinql
// Display name and picture for a person
@prefix foaf http://xmlns.com/foaf/0.1/
https://bob.me/profile#me {
foaf.name
foaf.img
}
{
"@context": {
"foaf": "http://xmlns.com/foaf/0.1/"
},
"@id": "https://bob.me/profile#me",
"foaf:img": [
"https://bob.me/avatar.jpg"
],
"foaf:name": [
"Bob"
]
}
Result (in JSON-LD)
Authors:
Dan Friedman
Andrei Sambra