Activity Streams/Primer/Representing Relationships Between Entities
Copied from Representing Relationships Between Entities
The Relationship
object is used to represent relationships between individuals. It can be used, for instance, to describe that one person is a friend of another, or that one person is a member of a particular organization. The intent of modeling Relationship in this way is to allow descriptions of activities that operate on the relationships in general, and to allow representation of Collections of relationships.
For instance, many social systems have a notion of a "friends list". These are the collection of individuals that are directly connected within a person's social graph. Suppose we have a user, Sally, with direct relationships to users Joe and Jane. Sally follows Joe's updates while Sally and Jane have a mutual relationship.
Using the Relationship
object, we can model these relationships as:
{ "@context": "https://www.w3.org/ns/activitystreams", "summary": "Sally's friends list", "type": "Collection", "items": [ { "summary": "Sally is influenced by Joe", "type": "Relationship", "subject": { "type": "Person", "name": "Sally" }, "relationship": "http://purl.org/vocab/relationship/influencedBy", "object": { "type": "Person", "name": "Joe" } }, { "summary": "Sally is a friend of Jane", "type": "Relationship", "subject": { "type": "Person", "name": "Sally" }, "relationship": "http://purl.org/vocab/relationship/friendOf", "object": { "type": "Person", "name": "Jane" } } ] }
The relationship
property specifies the kind of relationship that exists between the two individuals identified by the subject
and object
properties. Used together, these three properties form what is commonly known as a "<a href="http://patterns.dataincubator.org/book/reified-statement.html">reified statement</a>" where subject
identifies the subject, relationship
identifies the predicate, and object
identifies the object.
While use of reified statements can be problematic and confusing in certain situations, their use within the Activity Streams vocabulary to describe relationships provides a straightforward mechanism of describing changes to an individual's social graph. For instance, to indicate that Sally has created a new relationship to user Matt, an implementer can use the Relationship
object together with the Create
activity:
{ "@context": "https://www.w3.org/ns/activitystreams", "summary": "Sally became a friend of Matt", "type": "Create", "actor": "http://sally.example.org", "object": { "type": "Relationship", "subject": "http://sally.example.org", "relationship": "http://purl.org/vocab/relationship/friendOf", "object": "http://matt.example.org", "startTime": "2015-04-21T12:34:56" } }
Additionally, modeling the relationship in this way allows implementers to articulate additional properties of the relationship itself. For instance, the date and time at which the relationship began or ended.
Implementations may reuse existing vocabularies that have been developed for the purpose of describing relationships, or create their own guided by requirements of their particular implementation. Existing vocabularies include the "Friend of a Friend" and "Relationship" vocabularies.
Modeling "friend requests"
One common use case for many social platforms is the establishment of symmetrical "friend" relationships, in which one user initially extends a request to another user to establish a new connection. Once the connection is made, both users automatically begin receiving notifications about activities performed by the other, and the established relationship becomes visible in either user's "friends list".
The initial "friend request" can be modeled by composing the Offer
and Relationship
object types as in the following example:
{ "@context": "https://www.w3.org/ns/activitystreams", "id": "http://example.org/connection-requests/123", "summary": "Sally requested to be a friend of John", "type": "Offer", "actor": "acct:sally@example.org", "object": { "summary": "Sally and John's friendship", "id": "http://example.org/connections/123", "type": "Relationship", "subject": "acct:sally@example.org", "relationship": "http://purl.org/vocab/relationship/friendOf", "object": "acct:john@example.org" }, "target": "acct:john@example.org" }
Assuming the "friend request" is accepted, the remaining steps in this common application scenario can be represented as a set of distinct activities:
{ "@context": "https://www.w3.org/ns/activitystreams", "summary": "Sally and John's relationship history", "type": "Collection", "items": [ { "summary": "John accepted Sally's friend request", "id": "http://example.org/activities/122", "type": "Accept", "actor": "acct:john@example.org", "object": "http://example.org/connection-requests/123", "inReplyTo": "http://example.org/connection-requests/123", "context": "http://example.org/connections/123", "result": [ "http://example.org/activities/123", "http://example.org/activities/124", "http://example.org/activities/125", "http://example.org/activities/126" ] }, { "summary": "John followed Sally", "id": "http://example.org/activities/123", "type": "Follow", "actor": "acct:john@example.org", "object": "acct:sally@example.org", "context": "http://example.org/connections/123" }, { "summary": "Sally followed John", "id": "http://example.org/activities/124", "type": "Follow", "actor": "acct:sally@example.org", "object": "acct:john@example.org", "context": "http://example.org/connections/123" }, { "summary": "John added Sally to his friends list", "id": "http://example.org/activities/125", "type": "Add", "actor": "acct:john@example.org", "object": "http://example.org/connections/123", "target": { "type": "Collection", "summary": "John's Connections" }, "context": "http://example.org/connections/123" }, { "summary": "Sally added John to her friends list", "id": "http://example.org/activities/126", "type": "Add", "actor": "acct:sally@example.org", "object": "http://example.org/connections/123", "target": { "type": "Collection", "summary": "Sally's Connections" }, "context": "http://example.org/connections/123" } ] }
As illustrated in this example, accepting the "friend request" results in four additional activities including: John following Sally, Sally following John, John adding the relationship with Sally to his collection of Connections, and Sally adding the relationship with John to her collection of Connections.
In this example,
- The optional
result
property is used within theAccept
activity to identify the additional activities that occurred as a result of the accept. - The optional
context
property is used to relate the various activities back to a common reference point, which in this example is the relationship being established. Thecontext
allows an implementation to efficiently group related activities together for display or analytic purposes.