JSONLD mixing vocabulary activitystreams & schema.org/

JSON-LD confusion, how to add a version - Schema.org Property to this sample?

{"@context": "https://www.w3.org/ns/activitystreams",
 "type": "Create",
 "id": "https://social.example/alyssa/posts/a29a6843-9feb-4c74-a7f7-081b9c9201d3",
 "to": ["https://chatty.example/ben/"],
 "actor": "https://social.example/alyssa/",
 "object": {"type": "Note",
            "id": "https://social.example/alyssa/posts/49e2d03d-b53a-4c4c-a95c-94a6abf45a19",
            "attributedTo": "https://social.example/alyssa/",
            "to": ["https://chatty.example/ben/"],
            "content": "Say, did you finish reading that book I lent you?"}}

@naturzukunft
The simplest (even though it looks ugly) JSON-LD way of adding a version property would be just to use its full URL as the property name, like this:

{
   "@context": "https://www.w3.org/ns/activitystreams",
   "type": "Create",
   "object": {
      "https://schema.org/version": "1.0",
      ...
   },
  ...
}

But because that’s awkward to read, JSON-LD basically was created, to be able to move the URL part into the @context. So you can do something like this:

{
   "@context": [
      "https://www.w3.org/ns/activitystreams",
      {
        "version": "https://schema.org/version"
      }
   ],
   "type": "Create",
   "object": {
      "version": "1.0",
      ...
   },
  ...
}

So that’s basically the easiest way to think about JSON-LD:

  1. It wants to use full URLs, for global uniqueness of property values.
  2. Because full URLs are awkward to read, the "shortPropertyName": "https://full.url.example" mapping is moved to the @context.

And moving the property-to-url mapping to the context means either adding it to the object’s @context array (this is called the inline context), OR you can move it to an externally hosted context file, and just provide the URL to it (that’s what https://www.w3.org/ns/activitystreams is – an externally hosted context file that contains a bunch of property-to-url mapipngs).

This also suggest a basic general data modeling flow, when you’re extending AP (or anything else that involves JSON-LD):

  1. You start with a JSON object with no @context, and sketch out the properties you want.
  2. You look at Schema.org and other vocabularies (that have existing context files) to see if they have properties that you can reuse. And if so, you can just add the URLs to those contexts to the object’s @context property.
  3. If you need a field that doesn’t exist in Schema.org or similar places, you can pick a URL for it (say, a section on a Gitlab README), and add an inline mapping of the field to url to the object’s context array.
  4. Later, when your design is finalized, you can move the field-to-url mapping out of the inline context array, to an externally hosted file.

Does that help?

2 Likes

If i convert the following with EasyRdf - Converter

{
   "@context":[
      "https://www.w3.org/ns/activitystreams",
      {
         "schema":"https://schema.org/"
      },
      {
         "version":{
            "@id":"schema:version",
            "@type":"xsd:long"
         }
      }
   ],
   "type":"Create",
   "version":1,
   "id":"https://social.example/alyssa/posts/a29a6843-9feb-4c74-a7f7-081b9c9201d3",
   "to":[
      "https://chatty.example/ben/"
   ],
   "actor":"https://social.example/alyssa/",
   "object":{
      "type":"Note",
      "id":"https://social.example/alyssa/posts/49e2d03d-b53a-4c4c-a95c-94a6abf45a19",
      "attributedTo":"https://social.example/alyssa/",
      "to":[
         "https://chatty.example/ben/"
      ],
      "content":"Say, did you finish reading that book I lent you?"
   }
}

to turtle, i get:

@prefix as: <https://www.w3.org/ns/activitystreams#> .
@prefix ns0: <https://schema.org/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<https://social.example/alyssa/posts/a29a6843-9feb-4c74-a7f7-081b9c9201d3>
  a as:Create ;
  ns0:version "1"^^xsd:long ;
  as:actor <https://social.example/alyssa/> ;
  as:object <https://social.example/alyssa/posts/49e2d03d-b53a-4c4c-a95c-94a6abf45a19> ;
  as:to <https://chatty.example/ben/> .

<https://social.example/alyssa/posts/49e2d03d-b53a-4c4c-a95c-94a6abf45a19>
  a as:Note ;
  as:attributedTo <https://social.example/alyssa/> ;
  as:content "Say, did you finish reading that book I lent you?"^^xsd:string ;
  as:to <https://chatty.example/ben/> .

Is there a way to give the Namespace “ns0” a name?

Also interesting!

{
   "@context":[
      "https://www.w3.org/ns/activitystreams",
"https://schema.org/docs/jsonldcontext.json"
   ],
   "type":"Create",
   "version":1,
   "id":"https://social.example/alyssa/posts/a29a6843-9feb-4c74-a7f7-081b9c9201d3",
   "to":[
      "https://chatty.example/ben/"
   ],
   "actor":"https://social.example/alyssa/",
   "object":{
      "type":"Note",
      "id":"https://social.example/alyssa/posts/49e2d03d-b53a-4c4c-a95c-94a6abf45a19",
      "attributedTo":"https://social.example/alyssa/",
      "to":[
         "https://chatty.example/ben/"
      ],
      "content":"Say, did you finish reading that book I lent you?"
   }
}

is converted to:

@prefix as: <https://www.w3.org/ns/activitystreams#> .
@prefix schema: <http://schema.org/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<https://social.example/alyssa/posts/a29a6843-9feb-4c74-a7f7-081b9c9201d3>
  a as:Create ;
  schema:actor "https://social.example/alyssa/"^^xsd:string ;
  schema:object <https://social.example/alyssa/posts/49e2d03d-b53a-4c4c-a95c-94a6abf45a19> ;
  schema:version 1 ;
  as:to <https://chatty.example/ben/> .

<https://social.example/alyssa/posts/49e2d03d-b53a-4c4c-a95c-94a6abf45a19>
  a as:Note ;
  as:attributedTo <https://social.example/alyssa/> ;
  as:content "Say, did you finish reading that book I lent you?"^^xsd:string ;
  as:to <https://chatty.example/ben/> .

How is the processor deciding which context to use? Is there a way to define a default one, or a kind of priority ?

1 Like

It appears that you can also use:

{"@context": [
    "https://schema.org", 
    "https://www.w3.org/ns/activitystreams"
 ],
 "type": "Create",
 "version": "1.0",
...

The expansion works when I put it into the JSON-LD playground. The “schema.org” context must be first since there are overlapping terms (actor, object, etc.). Apparently (I need to confirm it), the later contexts override the earlier ones? (Maybe @codenamedmitri can comment on that.)

[Edit: our messages crossed so there may be some overlap…]

Saw this. inthe JSON-LD 1.1 spec…

Duplicate context terms are overridden using a most-recently-defined-wins mechanism. (Section 4.1)

1 Like

Great, that looks fine!

{
   "@context":[
      "https://schema.org/docs/jsonldcontext.json",
      "https://www.w3.org/ns/activitystreams"
   ],
   "type":"Create",
   "version":1.1,
   "id":"https://social.example/alyssa/posts/a29a6843-9feb-4c74-a7f7-081b9c9201d3",
   "to":[
      "https://chatty.example/ben/"
   ],
   "actor":"https://social.example/alyssa/",
   "object":{
      "type":"Note",
      "id":"https://social.example/alyssa/posts/49e2d03d-b53a-4c4c-a95c-94a6abf45a19",
      "attributedTo":"https://social.example/alyssa/",
      "to":[
         "https://chatty.example/ben/"
      ],
      "content":"Say, did you finish reading that book I lent you?"
   }
}

→

@prefix as: <https://www.w3.org/ns/activitystreams#> .
@prefix schema: <http://schema.org/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<https://social.example/alyssa/posts/a29a6843-9feb-4c74-a7f7-081b9c9201d3>
  a as:Create ;
  schema:version 1.100000e+0 ;
  as:actor <https://social.example/alyssa/> ;
  as:object <https://social.example/alyssa/posts/49e2d03d-b53a-4c4c-a95c-94a6abf45a19> ;
  as:to <https://chatty.example/ben/> .

<https://social.example/alyssa/posts/49e2d03d-b53a-4c4c-a95c-94a6abf45a19>
  a as:Note ;
  as:attributedTo <https://social.example/alyssa/> ;
  as:content "Say, did you finish reading that book I lent you?"^^xsd:string ;
  as:to <https://chatty.example/ben/> .
1 Like

@stevebate do you have an idea, why the inbox is compacted like that ?

"as:inbox": {
    "id": "http://localhost:8081/actor/0815/inbox"
  }

See JSON-LD Playground

Thanks

The expanded data references https://www.w3.org/ns/activitystreams#inbox. That’s not the correct URI. The as:inbox term is aliased to http://www.w3.org/ns/ldp#inbox. When I use that in the expanded data, it compacts like I would expect.

1 Like
# To match the JSON-LD namespace, the inbox must be in the ldp namespace.
# I verified this using JSON-LD Playground with an example Actor object.
ldp:inbox # :inbox
  a owl:ObjectProperty ;

:rofl: you are my hero :wink:
Then i’ve to check my vocab, sure there is an error.

now the response of the rdf-pub actor request looks fine:

{
  "id" : "http://localhost:8081/actor/0815",
  "type" : "Person",
  "inboxSparql" : "http://localhost:8081/actor/0815/inbox/sparql",
  "outboxSparql" : "http://localhost:8081/actor/0815/outbox/sparql",
  "identifier" : "0815",
  "version" : {
    "type" : "xsd:long",
    "@value" : "1"
  },
  "inbox" : "http://localhost:8081/actor/0815/inbox",
  "outbox" : "http://localhost:8081/actor/0815/outbox",
  "preferredUsername" : "max",
  "@context" : [ "https://schema.org/docs/jsonldcontext.json", "https://www.w3.org/ns/activitystreams", "https://rdf-pub.org/schema/rdf-pub-context.json" ]
}

Looking foreward to test it with AndStatus but still waiting for my Admin setting up a server.
And i have respect for httpsignature, but i have to do it sometime

2 Likes