LDflex for Solid
Simple access to data in Solid pods through LDflex expressions
This library is a configuration of the LDflex language for the Solid ecosystem. It configures LDflex with:
- a JSON-LD context for Solid
- a Solid-authenticated query engine (Comunica or rdflib.js)
- useful data paths for Solid
LDflex expressions occur for example on Solid React components, where they make it easy for developers to specify what data they want to show. They can also be used as an expression language in any other Solid project or framework.
Creating data paths
Once you obtain the solid.data
object, start writing data paths from the following entry points.
The user
entry point
The solid.data.user
path can query data about the currently logged in user, such as:
solid.data.user.firstName
yields the user's first name(s)solid.data.user.email
yields the user's email address(es)solid.data.user.friends
yields the user's friend(s)solid.data.user.friends.firstName
yields the user's friends' first name(s)
The any URL entry point
The solid.data[url]
path can query data about any subject by URL, such as:
solid.data['https://ruben.verborgh.org/profile/#me'].firstName
solid.data['https://ruben.verborgh.org/profile/#me'].email
solid.data['https://ruben.verborgh.org/profile/#me'].friends
solid.data['https://ruben.verborgh.org/profile/#me'].friends.firstName
Specifying properties
As you can see in the above examples, an LDflex path starts with an entry point and is followed by property names, which can be:
- abbreviations such as
firstName
(which expands tohttp://xmlns.com/foaf/0.1/givenName
) - prefixed names such as
foaf:givenName
(which expands tohttp://xmlns.com/foaf/0.1/givenName
) - full URLs such as
http://xmlns.com/foaf/0.1/givenName
The abbreviations and prefixed names are expanded using a JSON-LD context. You can find some inspiration about what to ask for in this context.
You can access data using any vocabulary you want and, when included in the JSON-LD context, in multiple ways. For example:
- FOAF:
solid.data.user.name
solid.data.user.foaf_name
solid.data.user.foaf$name
solid.data.user['foaf:name']
solid.data.user['http://xmlns.com/foaf/0.1/name']
- vCard:
solid.data.user.vcard_fn
solid.data.user.vcard$fn
solid.data.user['vcard:fn']
solid.data.user['http://www.w3.org/2006/vcard/ns#fn']
- Schema.org:
solid.data.user.schema_name
solid.data.user.schema$name
solid.data.user['schema:name']
solid.data.user['http://www.schema.org/name']
- Custom:
solid.data.user['http://example.org/my-ontology/name']
The traditional colon syntax for prefixes (schema:name
) can be substituted with an underscore (schema_name
) or dollar sign (schema$name
). This is because JavaScript keys with a colon require quotes (user['schema:name']
) whereas underscores and dollar signs can be used freely (user.schema_name
, user.schema$name
).
Installation
npm install @solid/query-ldflex
Usage
Within Node.js environments
const { default: data } = require('@solid/query-ldflex');
const ruben = data['https://ruben.verborgh.org/profile/#me'];
showProfile(ruben);
async function showProfile(person) {
const label = await person.label;
console.log(`\nNAME: ${label}`);
console.log('\nTYPES');
for await (const type of person.type)
console.log(` - ${type}`);
console.log('\nFRIENDS');
for await (const name of person.friends.firstName)
console.log(` - ${name} is a friend`);
}
If, instead of Comunica, you want to use the rdflib.js query engine, install @ldflex/rdflib
as a dependency of your project and use
const { default: data } = require('@solid/query-ldflex/lib/exports/rdflib');
When creating browser builds, it can be easier to simply tell webpack to replace @ldflex/comunica
by @ldflex/rdflib
.
In the browser
<script src="solid-auth-client.bundle.js"></script>
<script src="solid-query-ldflex.bundle.js"></script>
document.addEventListener('DOMContentLoaded', async () => {
const user = solid.data.user;
alert(`Welcome, ${await user.firstName}!`);
});
To replace Comunica by rdflib.js, opt for
<script src="solid-auth-client.bundle.js"></script>
<script src="rdflib.min.js"></script>
<script src="solid-query-ldflex.rdflib.js"></script>
Adding a custom JSON-LD context
In addition to the default properties, you might want to support your own:
console.log(solid.data.context); // the raw default JSON-LD context
await solid.data.context.extend({ // add new JSON-LD context
con: 'http://www.w3.org/2000/10/swap/pim/contact#',
preferred: 'con:preferredURI',
});
console.log(await solid.data.context); // the expanded JSON-LD context
// Now we can use both existing and new properties
const ruben = solid.data['https://ruben.verborgh.org/profile/#me'];
console.log(await ruben.name);
console.log(await ruben.preferred);
Be aware though that this leads to expressions that are less portable, because they only work when the additional context is added.
Resolving string expressions
LDflex expressions are actual JavaScript—not strings. There are times when strings are more useful though, such as when building declarative components that take LDflex expressions.
The solid.data
object exports a resolve
interface that transforms a string expression into an actual LDflex path. This string is appended to solid.data
to obtain the resulting path. For example:
solid.data.resolve('.user.firstName')
becomes the pathsolid.data.user.firstName
solid.data.resolve('["https://example.org/"].label')
becomes the pathsolid.data["https://example.org/"].label
For convenience, the starting dot and quotes inside of brackets can be omitted. If the path is a single URL, quotes and brackets can be omitted. The following strings will all resolve:
'.user.firstName'
'user.firstName'
'["https://example.org/"].label'
'[https://example.org/].label'
'https://example.org/'
License
©2018–present Ruben Verborgh, MIT License.