The Social API
Status of this document
2015-10-20 Document moved to W3C-Social Editor’s Draft. This document will no longer be updated.
An overview of the current state of specs that are inputs to the WG: ActivityPump, the Indieweb ecosystem (including Micropub and Webmention) and SoLiD; all of which are subject to ongoing development. Arranged based on Social API Requirements.
Optimistically, this has the potential to become a unified working draft. Ultimately an implementation of any subsection of this spec should be compatible with the equivalent subsection of one of the aforementioned specs. Sometimes the overlap between spec subsections is unclear (to me), which is where I’ve written all options out for now.
Overview
People and the content they create are the core componants of the social web; they make up the social graph. This document describes a standard way in which people can:
- connect with other people and subscribe to their content;
- create, update and delete social content;
- interact with other people’s content;
- be notified when other people interact with their content;
regardless of what that content is or where it is stored.
This provides the core building blocks for interoperable social systems.
This specification is divided into parts that can be implemented independantly as needed, or all together in one system, as well as extended to meet domain-specific requirements. Users can store their social data across any number of compliant servers, and use compliant clients hosted elsewhere to interact with their own content and the content of others. Put simply, this specification tells you:
- how to expose/consume social content (reading), and how to discover content someone has published.
- what to post, and where to, to create, update or delete content.
- how to ask for notifications about content (subscribing).
- how to send notifications about content or users (mentioning).
- how to expose profiles and relationships.
Reading
Each stream MUST have a globally unique identifier (HTTP URI). Each object in a stream MUST have a globally unique identifier (HTTP URI) in the @id
property, and MAY contain only this identifier, which can be dereferenced to retrieve all properties of an object.
A GET
on the identifier retrieves JSON[-LD] representation of the object or stream of objects, or an HTML representation from which the equivalent JSON representation can be parsed.
Content representation
Content SHOULD be represented according to ActivityStreams (JSON or JSON-LD) but MAY be structured according to an alternative syntax (eg. HTML with Microformats2 or HTML with RDFa).
Content SHOULD be described using the ActivityStreams vocabulary, but MAY use other vocabularies instead.
TODO: limit/paging
url
not @id
TODO: Example single object.
TODO: Example stream of objects.
Creating content
POST
a JSON object (see content representation) to the appropriate endpoint.
- ActivityPump:
POST
to"outbox": "..."
(See ActivityPump 7.4.1) - Micropub:
POST
torel="micropub"
(See Micropub) - SoLiD:
POST
to an LDP container (See SoLiD - Creating new resources)
Updating
Updating an object SHOULD have the side effect of notifying those subscribed and mentioned.
- ActivityPump:
POST
an AS2Update
Activity to theoutbox
endpoint. - Micropub:
POST
anmp-edit
action torel="micropub"
endpoint. - SoLiD:
PUT
orPATCH
the resource being updated.
Deleting
Deleting an object SHOULD have the side effect of notifying those subscribed and mentioned.
When an object is deleted, it SHOULD be replaced with a ‘tombstone’ containing its unique identifier, deleted (or last updated) date, and optionally replacement content (eg. “this post was removed”). Its URI SHOULD return a 410.
Note: using SHOULD not MUST to allow for silently deleting objects
- ActivityPump:
POST
an AS2Delete
Activity to theoutbox
endpoint. - Micropub:
POST
anmp-delete
action torel="micropub"
endpoint. - SoLiD:
DELETE
on the resource being deleted.
Discovery
One user may publish one or more streams of content. Streams may be generated automatically or manually, and might be segregated by post type, topic, audience, or any arbitrary criteria decided by the curator of the stream. The result of a GET
on the HTTP URI of a profile MAY include links to other streams, which a consumer could follow to read or subscribe to. Eg.
<link rel="feed" href="http://rhiaro.co.uk/tag/socialwg">
HTTP/1.1 200 OK .... Link: <http://rhiaro.co.uk/tag/socialwg>; rel="feed"
- h-feed:
rel="feed"
(See h-feed) - ActivityPump: contains some pre-defined ActivityStreams
Collections
, whose URIs are discoverable from the JSON returned byGET
ing a user’s profile, eg. via theinbox
,outbox
,favorites
properties; but not sure what scope is for linking to arbitrary collections. (See ActivityPump - Discovery)
Subscribing
An agent (client or server) may ask to be notified of changes to a content object (eg. edits, new replies) or stream of content (eg. objects added or removed from the stream).
Here are some options…
- ActivityPump: The subscriber posts a
Follow
Activity (JSON object) to the target’sinbox
endpoint, and adds the target to the subscriber’sFollowing
Collection. The target’s server adds the subscriber to the target’sFollowers
Collection, and subsequentlyPOST
s all new activities of the target to the subscriber’sinbox
endpoint. (See ActivityPump 7.4.2, 8 and 9.2.4) - SoLiD: The subscriber sends the keyword
sub
followed by an empty space and then the URI of the resource, to the target’s websockets URI. The target’s server sends a websockets message containing the keywordpub
, followed by an empty space and the URI of the resource that has changed, whenever there is a change. (See SoLiD - Live Updates) - PubSubHubbub: The subscriber discovers the target’s hub, and sends a form-encoded
POST
request containing values forhub.mode
(“subscribe”),hub.topic
andhub.callback
. When the target posts new content, the target’s server sends a form-encodedPOST
to the hub with values forhub.mode
(“publish”) andhub.url
and the hub checks the URL for new content andPOST
s updates to the subscriber’s callback URL. (See PuSH 0.4 and How To Publish And Consume PuSH) - Salmentions: The subscriber creates content that links to the target (eg. a reply) and sends a form-encoded
POST
containing values forsource
andtarget
to the target’s webmention webmention endpoint. The target verifies the link and includes a link back to the subscriber’s source on the target content. The target sends form-encodedPOST
requests containing values forsource
andtarget
to the webmention endpoint of every link in the content, including that of the subscriber, to indicate that there has been a change. (See webmention and salmentions)
A server may also receive notifications of changes to content it has not subscribed to: see mentioning.
Mentioning
(was ‘Notifications’)
A user may wish to push a notification to another user, for example because they have linked to (replied, liked, bookmarked, reposted, …) their content or linked to (tagged, addressed) the user directly.
- ActivityPump: When an Activity is posted to a user’s
outbox
endpoint, the server checks for values ofobject
,target
,inReplyTo
,to
,cc
, andbcc
; discovers theinbox
endpoint of any objects found, andPOST
s the Activity to the discoveredinbox
endpoints. Servers receiving such an Activity proceed to do the same for the target object to propagate the update further. (See ActivityPump 8.2) - Webmention: The target publishes a link to their ‘webmention endpoint’ via
rel="webmention"
. The source sends a form-encodedPOST
request containing values forsource
(the URL of a webpage with a link to the target) andtarget
(the URL of the webpage being linked to). The target MUST validate that the source really does link to target, and proceeds to do with this information as desired. (See webmention)
Note: we need to leave it open for users to refuse content they have not explicitly subscribed to, ie. nothing else should rely on implementation of Mentioning.
Profiles
The subject of a profile document can be a person, persona, organisation, bot, location, …whatever. Each profile document MUST have a globally unique identifier (HTTP URI). Performing a GET
on a profile document SHOULD return a JSON object containing attributes of the subject of the profile; MAY return objects the subject has created, such as an ActivityStreams Collection
; and SHOULD return at least one link to a stream of content (see discovery). The JSON representation of a profile document MAY be parsed from an HTML representation (eg. via Microformats (h-card
) or RDFa).
Relationships
Note: a user should not be required to publish their friends/followers, or may selectively publish them. However, if they’re going to (which is useful for eg. switching readers without having to resubscribe to everyone) we should make sure there’s a standard way of doing it.
Note: I think defining a vocabulary for types of relationships is out of scope and generally not very useful.
- ActivityPump: When a server receives a
Follow
Activity in itsinbox
, the subject is added to aFollowers
Collection
, which is discoverable from the subject’s profile.
Authorization and access control
- Bearer tokens for authentication
- Leave obtaining the bearer token out of the spec, since there are already several RFCs for ways to obtain bearer tokens.
TODO: Access control
- ActivityPump: see auth
- Indieweb: see private posts, private webmention
- SoLiD: see acl