Some Helper APIs to play SAFE with WebID and RDF.


RDF can be a pain.

It’s great once you’ve got it, but figuring out just how to describe your data, given the myriad of schemas and vocabs out there (yay decentralisation!). It can be a pain.

For us, this is clearly one of the largest blockers to people implementing RDF data in their applications. And we want RDF on SAFE. It makes sense to have it. To keep data portable. To keep users owning their data. We want RDF and we want to make it hard to get it wrong.

Even just for our own sanity! :stuck_out_tongue:

So as we were building out the POCs, we started creating some helper APIs to help simplify the process.

These are built atop the RDF Emualtion, we started creating APIs to abstract away the vocab-paralysis that can come with RDF, so when working with WebIds at least, it should be easy enough to get going.

A WebID Emulation

The WebId emulation makes creating a WebId profile document on SAFE, a simple function call:

const profile = {
  uri: 'safe://mywebid.gabriel',
  name: 'Gabriel Viganotti',
  nick: 'bochaco',
  website: 'safe://mywebsite.gabriel',
  image: 'safe://mywebsite.gabriel/images/myavatar',

const md = await authedApp.mutableData.newPublic(xorname, TYPE_TAG);
await md.quickSetup({});
const webId = await md.emulateAs('WebID');
await webId.create(profile);

This will create an RDF graph, populate it with your profile, which itself will have vocab descriptions of the data consistent with other SAFE WebIds. It creates a publicName and subdomain if needed, and populates those with appropriate RDF graphs too.

For now the profile is limited to name, nickname, img, website, but there’s nothing stopping us expanding this as we move forwards.

On top of that, we’ve added a few more helpers to the WebID emulation, to make update and serialise a breeze too!

Working it on the Web

In order to make working with already existing WebIds simpler, we added another new top level API to safe_app_nodejs: the (oh so imaginatively named) ‘web’ api: safe.web.

This features helpers for what could be more ‘normal’ SAFE tasks: createPublicName, getPublicNames, addWebIdToDirectory, getWebIds. (Bear in mind these will all generate RDF style versions of these containers, which are not currently compatible with older SAFE applications.)

The slightly ambiguous addWebIdToDirectory is used to provide a simple way of seeing all webids owned by an account. This is used as part of the webId.create emulation to save a reference to the webId’s URL to the public container, providing us one easy place to retrieve all webIds without having to request permissions to _publicNames, and then digging deeper into each public name to see if it is a webId or not. Saving us a couple of fetches.

The converse to this is the getWebIds,which will return a list of all webIds stored in the ‘directory’, (aka. the public container for now.)

All of these APIs are actively being used in both the Peruse POC and the WebId Manager.

More Help!?

That’s the last of the APIs we’ve added for the moment. But we’re aiming to provide as much help as we can to devs to help make adding RDF vocabs to their data, easy.

So comments, thoughts, PRs and suggestions are all suuuuuper welcome.


A few RDF n00b questions from me:
- so our app/site can see all WebIds that the user has available…Peruse was letting the user select which WebId to use, right? So to clarify, the idea is that if we’re building our own app from scratch, we’ll use the getWebIds to present similar ‘choose your webId’ functionality, and if we build a site meant for Peruse we don’t really need to worry about that, and will read the selected WebId directly from Peruse? edit3: this answered in the Medium article: “So web apps don’t actually have to worry about managing WebIds at all, they can focus on consuming the data”

  • would every app/site be expected to have the functionality to create new webIDs, or would that more likely be handled all through the WebId Manager? I guess probably too early to say / market will decide what expectations will be. How is it in the existing RDF&SOLID ecosystem?
  • When RDF data is created by our app/site, it gets tagged or otherwise linked with the WebId used to create it, right?

Edit: reading your other RDF thread now. Looks like it might have some of these answers.

Edit2: trimmed 3rd question after reading about RDFlib.js in other thread


Hey @drehb

On my phone, so apologies for brevity or typos!.

Would all apps create webids?

I’d hope not. Seems like there could be a range of apps to manage webids,but you choose your preference.

Any other app asking for perms for this ,I’d regard with suspicion. With webids existing a device shouldn’t need to bother with this. We could provide an API to open the management app if needed,eg.

Your second q: I imagine being up to the app/user. I don’t think that needs to be forced one way or the other


Another question - Looking at the patter app and the presentations that you guys have given, I can start to picture how everyone’s public data links together and can be crawled. Is it only really applicable to this publicly networked data, or do you guys envision user’s private data items also being stored in RDF graphs?


Everything, public, private, shared should ideally be RDF. This is the key point being made in my SAFE Plume demo at the DevCon.

Because then the different apps you use for private stuff can also work on each other’s non proprietary, non app specific data.

Also, you may wish to make use of semantics/crawling yourself on your private data, or on shared data, and of course to make some data that was once private public or shared.

Apps which keep proprietary formats will be less useful, and lock users in, which is what we are trying to get away from.