Activity Streams and Annotations

Hello Annotation WG,

I am James Snell, a member of the Social Web WG and editor of the
Activity Streams 2.0 FPWD the Social WG recently published. I had the
pleasure of speaking with several of you during the TPAC WG meetings
on Monday and Tuesday. (a definite thank you for the chairs for
arranging the short cross-WG get together on Tuesday).

During that face-to-face, the possibility of leveraging the Activity
Streams work within Annotations was discussed and I took as an action
item to draw up a few simple examples of how the Annotation data model
and Activities could work together. I've documented a few initial
thoughts here (focusing strictly on the data modeling and syntax
issues and ignoring API and protocol for now).

Based on what I've been able to gather, the Annotation WG appears to
be using the Open Annotation Data Model [1] as the starting point,
with JSON-LD as the primary serialization. For our purposes here, this
is good. Activity Streams 2.0 is also defined as a vocabulary with a
JSON-LD serialization. So far so good.

In order to level set a bit, I'll first give a brief overview of the
Activity Streams model...

An Activity is effectively an Actor-Verb-Object statement. Using it,
we can express concepts such as "Sally uploaded a photo" or "John
comments on this blog post". What Activities does not do is provide a
model for the actors, verbs and objects themselves. In other words, in
the above examples, we look to other vocabularies to describe what a
"Sally" is, what "uploaded" means and what a "photo" is.

(btw, so it's clear... currently, our JSON-LD @context definition is
located at http://asjsonld.mybluemix.net, that'll eventually get moved
but the examples below will use this temporary location)

{
  "@context": "http://asjsonld.mybluemix.net",
  "actor": "acct:sally@example.org",
  "verb": "http://example.org/verbs/Upload",
  "object": {
    "@id": "http://photos.example.org/album/abc.png",
    "@type": "http://example.org/types/Photo",
    "displayName": "A picture of my cat"
  }
}

This example ought to be fairly straightforward. Note the "verb"
property. This communicates the type of action that has been taken.
The example above is an illustration of the way the previous version
of Activity Streams took to express the action type. The Social WG is
currently discussing whether or not we can simply drop "verb" in favor
of "@type". If we do so, the example becomes:

{
  "@context": "http://asjsonld.mybluemix.net",
  "@type": "http://example.org/verbs/Upload",
  "actor": "acct:sally@example.org",
  "object": {
    "@id": "http://photos.example.org/album/abc.png",
    "@type": "http://example.org/types/Photo",
    "displayName": "A picture of my cat"
  }
}

Modeling Verbs as Nouns proves to be quite useful in a wide variety of
scenarios. For the Annotation examples, I will use this latter
approach.

Looking over the Open Annotations Data Model, I see that there are a
number of modules. The core, properties, however, seem to be hasBody,
hasTarget, annotatedBy, annotatedAt, serializedBy, serializedAt, and
motivatedBy. Let's just focus on a couple of these:

{
  "@context": "...",
  "oa:hasBody": {
    "@type": "xsd:string",
    "@value": "A simple value"
  },
  "oa:hasTarget": {
     "@id": "http://example.org/foo##a+text-fragment
  },
  "oa:annotatedBy": "acct:sally@example.org",
  "oa:annotatedAt": "2014-10-30T12:34:56Z",
  "oa:motivatedBy": "oa:editing"
}

Within Activity Streams, we have two possible ways of moving forward:

A. We can use the OA vocabulary within the direct object of an
Activity statement:

{
  "@context": "http://asjsonld.mybluemix.net",
  "@type": "http://example.org/verbs/Upload",
  "actor": "acct:sally@example.org",
  "object": {
    "@context": "...",
    "oa:hasBody": {
      "@type": "xsd:string",
      "@value": "A simple value"
    },
    "oa:hasTarget": {
       "@id": "http://example.org/foo##a+text-fragment
    },
    "oa:annotatedBy": "acct:sally@example.org",
    "oa:annotatedAt": "2014-10-30T12:34:56Z",
    "oa:motivatedBy": "oa:editing"
  }
}

Which works reasonably well but has some issues. Even more
interesting, however, is that we can...

B. We can leverage the JSON-LD to map somewhat seamlessly between the
Activity Streams and OA Vocabularies:

{
  "@context": [
    "http://asjsonld.mybluemix.net",
    {
      "oa": "http://www.w3.org/ns/oa#",
      "object": "oa:hasBody",
      "target": "oa:hasTarget",
      "actor": "oa:annotatedBy",
      "published": "oa:annotatedAt",
      "generator": "oa:serializedBy"
    }
  ],

  "@type": "oa:Annotation",
  "actor": "acct:sally@example.org",
  "object": {
    "@type": "xsd:string",
    "@value": "This is a simple annotation"
  },
  "target": "http://example.org/something##this+is+something",
  "oa:motivatedBy": {
    "@type": "oa:Motivation",
    "@id": "oa:editing"
  }
}

(You can view this example in the JSON-LD Playground here:
http://tinyurl.com/o4zxrwh)

If you ignore the JSON-LD @context, this looks like a typical, fairly
ordinary Activity Streams document. However, the @context redefines
the actor, object and target to map directly to the OA annotatedBy,
hasBody and hasTarget properties. The oa:Annotation becomes just
another type of Activity. Because AS currently does not have a means
of expressing the motivation behind the activity, we cannot map
oa:motivatedBy, but that's ok, things still work.

Btw, the normalized form of the above example comes out to:

<http://www.w3.org/ns/oa#editing>
<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>
<http://www.w3.org/ns/oa#Motivation> .
_:c14n0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>
<http://www.w3.org/ns/oa#Annotation> .
_:c14n0 <http://www.w3.org/ns/oa#annotatedBy> "acct:sally@example.org" .
_:c14n0 <http://www.w3.org/ns/oa#hasBody> "This is a simple
annotation"^^<xsd:string> .
_:c14n0 <http://www.w3.org/ns/oa#hasTarget>
"http://example.org/something##this+is+something" .
_:c14n0 <http://www.w3.org/ns/oa#motivatedBy>
<http://www.w3.org/ns/oa#editing> .

The ability to express the OA Annotation Data Model using Activity
Streams 2.0 syntax is a pretty neat trick. I was actually somewhat
surprised that it worked so well at the first try. Regardless,
however, if the Annotation WG opted to go with your own JSON-LD
serialization, things would still just work. The Activity and
Annotation vocabularies appear to be quite compatible with one
another.

Hopefully this is at least helpful. Btw, just for reference, I've
provided links to our Editor's Drafts below as well.

- James Snell

[1] http://www.openannotation.org/spec/core/index.html
[2] http://jasnell.github.io/w3c-socialwg-activitystreams/activitystreams2.html
[3] http://jasnell.github.io/w3c-socialwg-activitystreams/activitystreams2-vocabulary.html

Received on Thursday, 30 October 2014 15:09:22 UTC