JSON-LD in SOLID-CLIENT

Hi everyone!! Quick and simple question: How can we parse/serialize a Thing to JSON-LD using the solid-client framework?

This is what I got so far:

  // Get Dataset
  const endpoint = "https://path.to/pod/container/";
  const options = { fetch: session.fetch };
  const dataset = await getSolidDataset(endpoint, options);
  // Get Thing
  const thing = getThing(pod, endpoint);
  // THIS IS WHERE I'M STUCK
  const result = {code that magically turns thing into JSON-LD}
  // Return JSON-LD formatted Thing
  res.send(result);

Thank you so much! And if this feature is not yet available I would love to know where I can post a ticket or issue to suggest it :yum: Cheers!

At present we don’t have direct functionality in @inrupt/solid-client for this. Off top of head, you’d need to go through toRdfJsDataset and then use that to serialise to JSON-LD.

As an aside, in your code above the first argument to getThing would be dataset not pod.

Docs: Module: rdfjs — Inrupt solid-client Documentation

You may also like: GitHub - digitalbazaar/jsonld.js: A JSON-LD Processor and API implementation in JavaScript

Here’s how the solidThing.toJSONLD() method for converting a single thing from a Solid Dataset, to JSON-LD looks to me at the moment:

// 1. **`getDataset`**: Retrieves all things from a container in a given endpoint.
const pod = await getSolidDataset(endpoint, options);
// 2. **`getThing`**: Retrieves a single thing from the Solid dataset
const thing = getThing(pod, endpoint);
// 3. **`createSolidDataset`**: Create a new Solid dataset just for that thing
let dataset = createSolidDataset();
// 4. **`setThing`**: Set that thing to its dedicated Solid dataset
dataset = setThing(dataset, thing);
// 5. **`toRdfJsDataset`**: Serialize that Solid dataset to an RDF/JS dataset
const rdfJsDataset = toRdfJsDataset(dataset);
// 6. **`rdfJsDataset.match`**: Serialize the RDF/JS dataset to Quads
const quads = rdfJsDataset.match();
// 7. **`new JsonLdSerializer()`**: Create a new JSON-LD serializer
const serialiser = new JsonLdSerializer();
// 8. **`serializer.write(quad)`**: Add every quad to the serializer
for (const quad of quads)
  serialiser.write(quad);
serialiser.end();
// 9. **`stringifyStream(serializer)`**: Generate string with JSON-LD resulting serialization
const result = stringifyStream(serialiser);
// 10. **`JSON.parse`**: Parse JSON-LD string to JSON for use in code
const parsed = JSON.parse(await result);

Additionally, one could compact that JSON-LD with a given context using:

const compact = await jsonld.compact(parsed, context);

Now, the question becomes: Is this optimal though? Is there a better way to do this? :hushed:

Thank you so very much @ThisIsMissEm

Forwarding Solid to JSON-LD serialization? · Issue #1732 · inrupt/solid-client-js · GitHub for completeness

You could always take a query approach like this depending on your use case and skip the conversion to and from thing.

Here the source is just your endpoint


import { QueryEngine } from '@comunica/query-sparql-solid';
import { type Session } from '@inrupt/solid-client-authn-browser';
const stringifyStream = require('stream-to-string');


async function getJsonLD(webId: string, source: string, session: Session) {
  const engine = new QueryEngine();

  const result = await engine.resultToString(
    await engine.query(`CONSTRUCT { <${webId}> ?p ?o } WHERE { <${webId}> ?p ?o }`, {
      sources: [ source ],
      '@comunica/actor-http-inrupt-solid-client-authn:session': session
    }),
    'application/ld+json'
  );

  return stringifyStream(result.data)
}
1 Like

Ah, I just realised that you can also skip solid-client for getting the Thing, since you’re already calling match, which does that:

// 1. **`getDataset`**: Retrieves all things from a container in a given endpoint.
const pod = await getSolidDataset(endpoint, options);
// 2. **`toRdfJsDataset`**: Serialize that Solid dataset to an RDF/JS dataset
const rdfJsDataset = toRdfJsDataset(pod);
// 3. **`rdfJsDataset.match`**: Extract the RDF/JS dataset's Quads that have `endpoint` as their Subject (i.e. a Thing)
const quads = rdfJsDataset.match(endpoint);
// 4. **`new JsonLdSerializer()`**: Create a new JSON-LD serializer
const serialiser = new JsonLdSerializer();
// 5. **`serializer.write(quad)`**: Add every quad to the serializer
for (const quad of quads)
  serialiser.write(quad);
serialiser.end();
// 6. **`stringifyStream(serializer)`**: Generate string with JSON-LD resulting serialization
const result = stringifyStream(serialiser);
// 7. **`JSON.parse`**: Parse JSON-LD string to JSON for use in code
const parsed = JSON.parse(await result);
1 Like

That also works! Thank you @Vincent! Although performance wise, Comunica rocks! :metal:t4:

1 Like

Hi,

Is there any format available for storing VC(Verifiable Credential) into solid pod?

If possible, then is it JSON-LD format or any other type? What is it?

I believe you asked this here: Storing user preferences in a POD - #8 by nicolasmondada

Please don’t ask the same question in multiple places, it makes it hard for folks to find answers in the future.

Sorry, my bad. Thank you for informing me.