Linked Data Notifications

This version:
https://linkedresearch.org/ldn/
Latest published version:
https://www.w3.org/TR/ldn/
Previous version:
https://www.w3.org/TR/2016/WD-ldn-20160913/
Notifications Inbox
inbox/
Annotation Service
annotation/
Published
Modified
Repository
Github
Issues

Abstract

Linked Data Notifications is a protocol that describes how servers (receivers) can have messages pushed to them by applications (senders), as well as how other applications (consumers) may retrieve those messages. Any resource can advertise a receiving endpoint (Inbox) for the messages. Messages are expressed in RDF, and can contain any data.

Status of This Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.

This document was published by the Social Web Working Group as a Working Draft. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to public-socialweb@w3.org (subscribe, archives). All comments are welcome.

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 1 September 2015 W3C Process Document.

Introduction

Linked Data Notifications (LDN) is a specialized use of Linked Data Platform [LDP] for sending and consuming notifications. It is not dependent on a complete implementation of LDP, but an easy-to-implement subset. This specification describes the particular features necessary to make it easy to exchange notifications in a decentralised, interoperable way.

This protocol supports a modular approach to creating and storing data, in particular a decoupling between applications and data storage. Thus, where senders, receivers and consumers of notifications are independently implemented and run on different technology stacks, this protocol allows them to seamlessly work together.

  • This specification enables the notion of a notification as an individual entity with its own URI which can be retrieved and reused.
  • This specification deliberately does not define the vocabulary of the notification contents in order to allow for use in a range of different application domains.
  • Authentication and verification of notifications is encouraged, but the mechanism to do so is at the discretion of receivers and consumers, as needs differ according to types of notification and different application domains.

Social Web Working Group

LDN is one of several related specifications being produced by the Social Web Working Group. Implementers interested in alternative approaches and complimentary protocols should start by reading the overview document Social Web Protocols.

Overview

Overview of Linked Data Notifications

A sender is triggered, either by a human or an automatic process, to deliver a notification to a server. The notification is data intended for the attention of the receiver, for example: a personal message from a friend; a pingback link; a comment on a blog post; an invitation to collaborate; a calendar reminder.

The sender discovers where to deliver the notification based on the addressee or subject of the notification (the receiver) who advertises the appropriate location to send it to (the Inbox). Any resource can have its own Inbox. The receiver also exposes the notification data (according to appropriate access control) for use by consumers.

Consumers discover the location of the Inbox in the same way as the sender, and may perform further processing on the notifications, combine it with some other data, or simply present it in a suitable human-readable way.

Summary

Senders and consumers discover a resource's Inbox URL through a relation in the HTTP Link header or body of the resource.

The Sender:

  • Creates the body of the notification according to the needs of application.
  • Sends the notification to the Inbox URL by making a POST request, containing the body in JSON-LD or in another serialization acceptable by the server.

The Receiver:

  • Responds to GET requests made to the Inbox URL with a JSON-LD representation (or if possible, requested serialization) of the URLs of the notifications that have previously been sent to the Inbox.
  • Accepts POST requests at the Inbox URL to create notifications.
  • Optionally enforces constraints on notifications sent to the Inbox.

The Consumer:

  • Retrieves the contents of the Inbox URL with a GET request, and uses according to the needs of application.

Conformance

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119]. As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative.

Conformance Classes

LDN implementations may be senders, receivers or consumers. The conformance criteria for each of these roles are described in their respective sections of this specification.

Exit Criteria

For this specification to advance to Proposed Recommendation, there must be at least two independent, interoperable implementations of each feature. Each feature may be implemented by a different set of products. There is no requirement that all features be implemented by a single product.

  • Independent implementations are developed by different parties and cannot share, reuse or derive form another qualifying implementation code which is directly pertinent to the implementation of this specification.
  • Interoperability occurs between senders and receivers, or between consumers and receivers, when the sender/consumer makes a request to the receiver, and the receiver sends the expected response, as defined by this specification.
  • An implementation is an LDN sender, receiver or consumer which implements the corresponding conformance class of the specification.

For the purposes of evaluating exit criteria, each of the following is considered a feature:

  • Advertising the Inbox of a given resource through the Link header.
  • Advertising the Inbox of a given resource through the body of the resource.
  • Sending a notification to the Inbox of a given target.
  • Receiving a notification and responding with the appropriate status code according to how it was processed and if it was accepted. Responding to GET requests on the Inbox with the Inbox listing, and responding to GET requests on the individual notifications with their representations.
  • Reading the Inbox listing of a given target.
  • Reading the individual notifications in the Inbox of a given target.

Protocol

This section describes the discovery of the URL to which notifications are delivered or read from (the Inbox) and the delivery mechanism. Notification contents are described in Payload.

Discovery

An Inbox, the endpoint which notifications are sent to or consumed from, can be discovered from any resource, for example a blog post, a user profile, a dataset, a video. The starting point for discovery is the resource which the notification is to or about: the target. Choosing the most appropriate target resource from which to begin discovery is at the discretion of the sender or consumer, since any resource (RDF or non-RDF) may have its own Inbox.

To discover the Inbox URL, senders and consumers:

  • make a HEAD or GET request on the target URL, to check for an HTTP Link header with a rel value of http://www.w3.org/ns/ldp#inbox
  • make a GET request on the target URL and, for RDF sources [RDF 1.1], the Inbox is the object of the predicate http://www.w3.org/ns/ldp#inbox.

These may be carried out in either order, but if the first fails to result in an Inbox the second MUST be tried. However, if the target contains a fragment identifier, the fragment is not part of the request to the server so any Inbox found in the Link headers will be for the resolved URL (without the fragment). Thus, senders and consumers SHOULD omit the Link header discovery when targeting URIs with fragment identifiers.

A resource MUST advertise only one Inbox. One Inbox MAY be used by multiple resources, for example using the same Inbox for replies to all of my blog posts and shares of all of my photos.

Issue 13

The namespace of the inbox property is to be finalised.

See also: https://github.com/csarven/ldn/issues/13

HEAD /profile HTTP/1.1
Host: user.example

HTTP/1.1 200 OK
Link: <https://user.example/inbox/>; rel="http://www.w3.org/ns/ldp#inbox"
                                        
Discovering an Inbox with a HEAD request.
GET /profile HTTP/1.1
Host: user.example
Accept: application/ld+json

HTTP/1.1 200 OK
Content-Type: application/ld+json

{
  "@context": "http://www.w3.org/ns/ldp",
  "@id": "https://user.example/profile",
  "inbox": "https://user.example/inbox/"
}
                                        
Discovering an Inbox with a GET request to retrieve JSON-LD.
GET /profile HTTP/1.1
Host: user.example
Accept: text/html

HTTP/1.1 200 OK
Content-Type: text/html

<a href="/inbox/" rel="http://www.w3.org/ns/ldp#inbox">My inbox</a>

                                        
Discovering an Inbox with a GET request to retrieve HTML.

Sending

Following discovery, senders MUST deliver notifications through a POST request to the Inbox URL. Senders can expect a 201 Created (with a Location Link header) in response to a successful request.

The sender MAY use an OPTIONS request to determine the RDF content types accepted by the server, and serialize the notification in the request body according to the value of the Accept-Post header [Accept-Post] returned. Otherwise, the body of the POST request MUST contain the notification payload in JSON-LD with header Content-Type: application/ld+json. The Content-Type header MAY include a profile URI [RFC6906].

The sender MAY include additional headers or content for the purposes of authentication or authorization e.g., Authorization: Bearer XXX.

Request:

POST /inbox/ HTTP/1.1
Host: user.example
Content-Type: application/ld+json

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "@id": "",
  "@type": "Announce",
  "actor": { "@id": "https://example.org/profile#alice" },
  "object": { "@id": "https://example.org/annotation-1" },
  "target": { "@id": "https://user.example/article#introduction" },
  "updated": "2016-06-23T15:03:01Z"
}
                                        
Example notification send request to an Inbox.

Response:

HTTP/1.1 201 Created
Location: https://user.example/inbox/notification-1
                                        
Example response to a request

Receiving

Receivers MUST support GET and POST requests on the Inbox URL. In LDP terms, an Inbox is a Container.

Receiving notifications

Upon receipt of a POST request, if the notification resource was processed successfully, receivers MUST respond with status code 201 Created and the Location header set to the URL from which the notification data can be retrieved (see Consuming). If the request was queued to be processed asynchronously, the receiver MUST respond with a status code of 202 Accepted and include information about the status of the request in the body of the response.

Receivers which enforce constraints on the notifications (see Security, Privacy and Content Considerations) SHOULD fail to process the notification if the constraints are not met and return the appropriate 4xx error code.

Receivers MUST accept notifications where the request body is JSON-LD, with the Content-Type: application/ld+json. The Content-Type header MAY include a profile URI [RFC6906].

Receivers MAY accept other RDF content types (e.g., text/turtle, text/html), and SHOULD advertise the content types they accept with an Accept-Post header on the Inbox URL.

HEAD /inbox/ HTTP/1.1
Host: user.example

HTTP/1.1 200 OK
Allow: GET, HEAD, OPTIONS, POST
Accept-Post: application/ld+json, text/turtle

POST /inbox/ HTTP/1.1
Host: user.example
Content-Type: application/ld+json

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "@id": "",
  "@type": "Announce",
  "actor": { "@id": "https://example.org/profile#alice" },
  "object": { "@id": "https://example.org/annotation-1" },
  "target": { "@id": "https://user.example/article#introduction" },
  "updated": "2016-06-23T15:03:01Z"
}

HTTP/1.1 201 Created
Location: https://user.example/inbox/notification-2
                                                
Example request and response
ActivityStreams 2.0 Support

Receivers SHOULD treat the application/activity+json media type as equivalent to application/ld+json; profile="http://www.w3.org/ns/activitystreams".

At Risk

This requirement may be moved to Social Web Protocols.

See also LDN issue #10 and SWP issue #36.

Making Inbox contents available to consumers

A successful GET request on the Inbox MUST return a HTTP 200 OK with the URIs of notifications, which MAY be subject to paging or access control restrictions at the receivers discretion (returning 4xx error codes as applicable). The receivers MAY only return URIs of notifications in the Inbox that the consumer is able to access.

Each notification URI MUST be related to the Inbox URL with the http://www.w3.org/ns/ldp#contains predicate. Each notification MUST be an RDF source. If non-RDF resources are returned, the consumer MAY ignore them.

The JSON-LD content type MUST be available for all resources, but clients may send Accept headers preferring other content types ([RFC7231] Section 3.4 - Content Negotiation). If the client sends no Accept header, the server may send the data in JSON-LD or any format which faithfully conveys the same information (e.g., Turtle).

Any additional description about the Inbox itself MAY also be returned (e.g., Constraints).

GET /inbox/ HTTP/1.1
Host: user.example
Accept: application/ld+json

HTTP/1.1 200 OK
Content-Type: application/ld+json

{
  "@context": "http://www.w3.org/ns/ldp",
  "@id": "https://user.example/inbox/",
  "contains": [
    { "@id": "https://user.example/inbox/notification-1" },
    { "@id": "https://user.example/inbox/notification-2" }
  ]
}
                                                
Results of GET request on Inbox.
ActivityStreams 2.0 Support

Receivers SHOULD treat the requests from consumers for application/activity+json as equivalent to application/ld+json; profile="http://www.w3.org/ns/activitystreams", but if doing so additionally MUST return JSON-LD in compacted form.

At Risk

This requirement may be moved to Social Web Protocols.

See also LDN issue #10 and SWP issue #36.

Consuming

Consumers retrieve the URIs of notifications in an Inbox through making a GET request on the Inbox URL (to find this URL, see discovery).

The URIs of the notifications MUST be discoverable through the http://www.w3.org/ns/ldp#contains predicate of the Inbox URL (see example for Inbox content).

When retrieving the Inbox or the individual notifications, the consumer SHOULD explicitly set the Accept header to indicate preferred content types, including for JSON-LD. Fetching the notifications — if any, how many, or according to a particular criteria (e.g., content-length, timestamp) — is at the discretion of the consumer.

The consumer MAY include additional headers or content for the purposes of authentication or authorization.

Consumers MAY perform additional fetching or inferring of information from the payload (e.g., dereferencing resources referenced in the notification to fetch their contents) at their discretion.

Note

Note that the fetched URI may not necessarily be same as the resolved value of @id against the base URI after serialising. In other words, the fetched URI can contain RDF statements with subject IRIs different than the requested URI itself. This is pertinent when the body of the notification uses relative IRIs.

Payload

The payload of the notification MUST be a JSON-LD unless another RDF syntax has been negotiated with the receiver. To allow for a wide variety of use cases, the actual vocabulary of the payload is deliberately not specified by this specification.

Payload Examples

This section is non-normative. Here are some examples of notification content:

Single Statement

A single triple statement is the simplest notification in terms of its data payload. It contains the most essential data which makes up a notification e.g, A note is a reply to an article:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "@id": "https://example.org/note",
  "inReplyTo": "https://example.net/article"
}
                                                
Example notification type: single statement in JSON-LD

This approach is useful if there is a need to further extend the statement's description or refer to it as a whole.

Qualified relations

A particular grouping of triples which describe and qualify the relations, i.e., the vocabulary in use typically gives meaning to the statements when consumed as a whole. The examples below tend to refer to external resources where the body of the content can be discovered.

ActivityStreams 2.0:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "@id": "",
  "@type": "Announce",
  "actor": { "@id": "https://example.org/profile#alice" },
  "object": { "@id": "https://example.org/annotation-1" },
  "target": { "@id": "https://user.example/article#introduction" },
  "updated": "2016-06-23T15:03:01Z"
}

                                                
Example notification type: qualified relation.

Semantic Pingback:

{
  "@id": "",
  "@type": "http://purl.org/net/pingback/Item",
  "http://purl.org/net/pingback/source":
    { "@id": "https://example.org/annotation-1" },
  "http://purl.org/net/pingback/target":
    { "@id": "https://user.example/article#introduction" }
}

                                                
Example notification type: Semantic Pingback.

Any data

This is typically in cases where an application may want to create a notification containing arbitrary information. A notification may contain the complete payload and not necessarily refer to the origin data (external resource).

{
  "@context": [
    { "sioc": "http://rdfs.org/sioc/ns#" },
    { "foaf": "http://xmlns.com/foaf/0.1/" }
  ],
  "@id": "",
  "@type": "sioc:Comment",
  "sioc:reply_of": { "@id": "https://user.example/article" },
  "sioc:created_at": "2015-12-23T16:44:21Z",
  "sioc:content" : "This is a great article!",
  "sioc:has_creator": {
    "@id": "https://example.org/profile/",
    "@type": "sioc:UserAccount",
    "sioc:account_of": { "@id": "https://example.org/profile#alice" },
    "sioc:avatar": { "@id": "https://example.org/profile/avatar.png" },
    "foaf:name": "Alice"
  }
}
                                                
Example notification type: any data.

Security, Privacy and Content Considerations

Constraints

This section is non-normative.

Inbox URLs can announce their own constraints (e.g., SHACL, Web Annotation Protocol) via an HTTP Link header or body of the resource with a rel value of http://www.w3.org/ns/ldp#constrainedBy. Senders should comply with constraint specifications or the receiver may reject their notification and return an appropriate 4xx error code.

Payload Verification

This section is non-normative.

Given the nature of the notification payload, consumers may want to take precautions when ascertaining the veracity of the contents. The open-world assumption applies here.

Sender Verification

Receivers SHOULD verify the sender of the notification, for example:

  • by having a whitelist of senders with write access to the Inbox
  • requiring authentication to enforce receiver's knowledge of every sender
  • retrieve a copy of the notification from the sender's domain to verify its origin
  • checking a digital signature which accompanies the notification

Preventing Abuse

Receivers SHOULD use constraints to filter unwarranted notifications from being created on the server and exposed by the Inbox. Consumers MAY also want to check the notifications against any constraints as announced by an Inbox before further processing or use.

If the sender has any services that listen on localhost that don't require authentication, it's possible for a malicious script to run at the Inbox endpoint that could cause the sender to make an arbitrary POST request to itself. Senders SHOULD NOT make POST requests to the Inbox that are localhost or a loopback IP address.

Receivers could consider implementing access control on the Inbox URL to restrict writing to a whitelist of trusted senders.

Privacy

In the case of sending sensitive information, the sender should be aware that the receiver may implement access control on the Inbox that allows for public reading of the contents.

Retrying Discovery

This section is non-normative.

Software that wants to retry discovery of the Inbox for a resource, or try discovery for multiple resources on the same domain, may want to follow the information in cache headers.

Target Ownership

This section is non-normative.

Publishers of the resources advertising an Inbox (target) should do so on a server they trust. Publishers must be aware that third-party access to headers or content could result in notifications being redirected.

Subscribing to Notifications

This section is non-normative.

This specification describes how consumers can read notifications from a receiver through pull, however consumers may want to ask to have incoming notifications or changes to Inbox's contents pushed to them. Similarly, receivers may wish to make a request for notifications from a particular sender. This kind of subscription mechanism left out of scope, but senders, receivers and consumers are not prohibited from making such an arrangement. Implementations that wish to enable subscribing may want to use existing mechanisms e.g., [ActivityPub], [PubSubHubbub], [The WebSocket Protocol], [HTTP Web Push].

Acknowledgements

..

Change Log

This section is non-normative.

Changes from 27 July 2016 WD to this version

  • Improve examples; update, syntactical fixes, @context in https
  • Typos, punctuation, naming
  • Use informative discretion about the payload

Changes from 24 August 2016 WD to this version

  • Typos, punctuation, naming
  • Add Exit Criteria
  • Clarify behaviour when Accept header is used and omitted
  • Add a note about subject of the relation for the Link header field
  • Add GET for possible Link header, clarify subject URI (for its Inbox) in target URL
  • Revise Abstract
  • Add consideration about target ownership
  • Mention 'any resource can have its own inbox'
  • Add Subscribing to Notifications section

Changes from 13 September 2016 WD to this version

  • Fix typos and links
  • Reorder sections to Sending, Receiving, Consuming
  • Update examples
  • Add reference to RFC7231
  • Clarify wording for URI discovery
  • Add sub-headings for the non-normative sections under Considerations
  • Add overview diagram

References

Normative references

[ldp]
Steve Speicher; John Arwe; Ashok Malhotra. W3C. Linked Data Platform 1.0. 26 February 2015. W3C Recommendation. URL: https://www.w3.org/TR/ldp/
[rdf11-concepts]
Richard Cyganiak; David Wood; Markus Lanthaler. W3C. RDF 1.1 Concepts and Abstract Syntax. 25 February 2014. W3C Recommendation. URL: https://www.w3.org/TR/rdf11-concepts/
[rfc2119]
S. Bradner. IETF. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[rfc6906]
E. Wilde. IETF. The 'profile' Link Relation Type. March 2013. Informational. URL: https://tools.ietf.org/html/rfc6906

Informative references

[accept-post]
J. Arwe; S. Speicher; E. Wilde. IETF. The Accept-Post HTTP Header. Internet Draft. URL: http://tools.ietf.org/html/draft-wilde-accept-post
[activitypub]
Christopher Webber; Jessica Tallon; Owen Shepherd. W3C. ActivityPub. 23 August 2016. W3C Working Draft. URL: https://www.w3.org/TR/activitypub/
[activitystreams-core]
James Snell; Evan Prodromou. W3C. Activity Streams 2.0. 12 July 2016. W3C Working Draft. URL: https://www.w3.org/TR/activitystreams-core/
[annotation-protocol]
Robert Sanderson. W3C. Web Annotation Protocol. 12 July 2016. W3C Candidate Recommendation. URL: https://www.w3.org/TR/annotation-protocol/
[pubsubhubbub]
Julien Genestoux. W3C. PubSubHubbub. W3C Editor's Draft. URL: https://github.com/w3c/pubshubhubbub/
[rfc6455]
I. Fette; A. Melnikov. IETF. The WebSocket Protocol. December 2011. Proposed Standard. URL: https://tools.ietf.org/html/rfc6455
[rfc7231]
R. Fielding, Ed.; J. Reschke, Ed.. Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content. June 2014. Proposed Standard. URL: https://tools.ietf.org/html/rfc7231
[shacl]
Holger Knublauch; Dimitris Kontokostas. W3C. Shapes Constraint Language (SHACL). 14 August 2016. W3C Working Draft. URL: https://www.w3.org/TR/shacl/
[social-web-protocols]
Amy Guy. W3C. Social Web Protocols. 23 August 2016. W3C Working Draft. URL: https://www.w3.org/TR/social-web-protocols/
[webpush]
M. Thomson; E. Damaggio; B. Raymor. IETF. Generic Event Delivery Using HTTP Push. Internet Draft. URL: https://tools.ietf.org/html/draft-ietf-webpush-protocol-08