如有错误或问题,请查阅勘误表。
本规范的英文版本为唯一规范性版本。非规范性翻译亦可能提供。
Copyright © 2017 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and permissive document license rules apply.
关联数据通知(Linked Data Notifications)是一种协议,用于描述服务器(接收方)如何被应用(发送方)推送消息,以及其他应用(消费者)如何获取这些消息。任何资源都可以声明一个用于接收消息的端点(Inbox 收件箱)。消息以 RDF 表达,并且可以包含任意数据。
状态更新(2017年5月):总览图中的链接已于2017年5月22日就地修复:它们此前指向了错误的内部锚点。
状态更新(2017年9月):概念 URI 已于2017年9月5日修正:此前指向了错误的内部 URI。
本节描述的是该文档发布时的状态。其他文档可能会取代本文件。当前 W3C 发布文档和本技术报告的最新版本可在 W3C 技术报告索引 https://www.w3.org/TR/ 查询。
本文件由社交网络工作组(Social Web Working Group)以推荐标准发布。如果你希望对本文档提出建议或意见,请发送邮件至public-socialweb@w3.org(订阅,归档)。欢迎所有反馈。
请参阅工作组的实现报告。
本文件已由 W3C 成员、软件开发者以及其它 W3C 组织及利益相关方审核,并经主管批准成为 W3C 推荐标准。本文件稳定,可作为参考或被其他文档引用。W3C 在发布推荐标准的职责是突出该规范并促进其广泛部署,从而提升 Web 的功能性和互操作性。
本文件由一组遵循2004年2月5日 W3C 专利政策的人员编写。W3C 保留一份相关专利公开信息列表;该页面还包含专利披露的说明。若个人实际知晓某专利涉及必要权利要求,则必须按照W3C 专利政策第6节的规定进行披露。
本文件遵循2017年3月1日 W3C 流程文档。
Web 上的数据不应被锁定在特定系统中,或只能被创建它的应用程序读取。用户应当能够自由地在应用之间切换并共享数据。应用程序会生成关于活动、交互以及新信息的通知,这些通知可以呈现给用户或做进一步处理。
关联数据通知(LDN) 支持通知在应用间跨界的共享和复用,无论它们是如何生成的。这使得系统架构更具模块化,数据存储可以与呈现或使用这些数据的应用分离。该协议旨在让独立开发、运行于不同技术栈的通知发送方、接收方和消费者,能够无缝协作,有助于推动 Web 交互的去中心化。
本规范不再将通知视为短暂或非持久实体,而允许把通知当作具有自身 URI 的独立实体。因此,通知可以被检索和复用。我们支持社交及其他领域的多种应用,因此通知内容由应用自行定义。鼓励实现通知的认证和验证,但具体机制由接收方和消费者自行确定,因为不同类型通知和应用场景需求不同。
发送方可由人或自动进程触发,将通知发送给服务器。通知即用于引起接收方注意的数据,例如:朋友的私信、pingback 链接、对博客文章的评论、协作邀请、日历提醒、科学观测等。
发送方选择目标资源进行通知推送,然后发现该目标的 Inbox(收件箱)位置,并将通知发送至该处。任何资源都可声明 Inbox。接收方按照合适的访问控制,对外公开通知数据供消费者使用。
消费者以与发送方相同的方式发现 Inbox 位置,并可对通知进一步处理、与其他数据结合,或以可读方式展现给用户。
发送方和消费者通过 HTTP Link 头或资源正文中的关联,发现资源的 Inbox URL。
发送方:
POST 请求发送通知,正文采用 JSON-LD 或服务器支持的其他序列化格式。接收方:
GET 请求,返回已接受通知的 URL 列表。GET 请求响应 JSON-LD(也可选用其它序列化)。POST 创建通知。消费者:
GET 请求检索 Inbox URL 内容,根据应用需求使用内容。LDN 是 [LDP] 关联数据平台的一个专门化用法,用于发送和消费通知。它不依赖于 LDP
的完整实现,而只需要易于实现的一个子集。理解本规范无需 LDP 知识,但已有 LDP 经验者会发现部分概念类似。我们描述其中必要的特性,以便去中心化、互操作地交换通知。LDN Inbox
可类比于 LDP 的 BasicContainer。
本文档中的 "MUST"、"MUST NOT"、"REQUIRED"、"SHALL"、"SHALL NOT"、"SHOULD"、"SHOULD NOT"、"RECOMMENDED"、"MAY" 及 "OPTIONAL" 这些关键词,应按 [RFC2119] 中的定义解释。凡标为非规范性章节的内容,以及本规范中的所有创作指引、图示、示例和注释,均为非规范内容。
LDN 实现 可以是 发送方、接收方或 消费者。这些角色的合规性要求见本规范相应章节。
本节描述了通知投递或获取的 URL(Inbox)的发现方法及投递机制。通知内容详见负载。
Inbox 是通知被发送或被消费的端点,可以从任何资源上发现,例如博客文章、用户档案、数据集、视频等。发现过程的起点是通知相关或欲送达的那个资源:即target。选择何种目标资源发起发现,由发送方或消费者自行决定,因为任何资源(无论 RDF 还是非 RDF)都可以拥有自己的 Inbox。
发送方和消费者通过如下方式发现 Inbox URL:
HEAD 或
GET 请求,并查看 Link 头,查找其 rel 值为
http://www.w3.org/ns/ldp#inbox。GET
请求以获取 RDF 表达([RDF
1.1]),其编码的 RDF 图中包含 http://www.w3.org/ns/ldp#inbox
关联。该关联的主语为目标资源,宾语为 Inbox。以上方法可任意顺序尝试,但若第一个方法无法得到 Inbox,则必须尝试第二个。发送方和消费者应当在明确以含片段标识符(fragment)的 URI 为目标时,省略 Link 头发现。
如果 target 含有片段标识符(fragment),则该片段不会包含在向服务器发起的请求中。发送方和消费者需注意,任何 Link 头中找到的
Inbox,实际上都是指向解析后的 URL,不含片段。详见 [Cool URIs for the Semantic Web - Hash URIs]。
一个资源必须只声明一个 Inbox。一个 Inbox 可以被多个资源复用,例如我的所有博客回复和所有相册分享都用同一个 Inbox。
发现示例 1:Link header
HEAD /article HTTP/1.1Host: example.orgAccept: application/ld+jsonHTTP/1.1 200 OKLink: <http://example.org/inbox/>; rel="http://www.w3.org/ns/ldp#inbox"
HEAD 请求发现 Inbox,并收到 Link 头的请求与响应。发现示例 2:JSON-LD
GET /profile HTTP/1.1Host: example.orgAccept: application/ld+jsonHTTP/1.1 200 OKContent-Type: application/ld+json{"@context": "http://www.w3.org/ns/ldp","@id": "http://example.org/profile","inbox": "http://example.org/inbox/"}
GET 请求获取 JSON-LD,返回紧凑形式的 Inbox。发现示例 3:可见 HTML
GET /event HTTP/1.1Host: example.orgAccept: text/html, application/ld+jsonHTTP/1.1 200 OKContent-Type: text/html;charset=utf-8<p about="http://example.org/event" typeof="http://schema.org/Event" lang="en"><a rel="http://www.w3.org/ns/ldp#inbox" href="/inbox/">RSVP</a> to event</p>
GET 请求获取 HTML 时发现 Inbox。Inbox 链接对人类可见,并通过 RDFa 标记方便机器发现 Inbox URL。
发现示例 4:隐藏 HTML
GET /article HTTP/1.1Host: example.orgAccept: text/html, application/ld+jsonHTTP/1.1 200 OKContent-Type: text/html;charset=utf-8<link href="/inbox/" rel="http://www.w3.org/ns/ldp#inbox" />
GET 请求获取 HTML 时发现 Inbox,通过 link 元素隐藏呈现,用于机器发现。
发现示例 5:隐藏 HTML
GET /article HTTP/1.1Host: example.orgAccept: text/html, application/ld+jsonHTTP/1.1 200 OKContent-Type: text/html;charset=utf-8<section id="results" about="#results"property="http://www.w3.org/ns/ldp#inbox" resource="/inbox/"></section>
GET 请求获取 HTML 时发现 Inbox,利用 RDFa 的 property 属性表达,使带片段
URI 的资源可作为目标。发现示例 6:Turtle
GET / HTTP/1.1Host: csarven.caAccept: text/turtle, application/ld+jsonHTTP/1.1 200 OKContent-Type: text/turtle;charset=utf-8<http://csarven.ca/#i><http://www.w3.org/ns/ldp#inbox> <http://csarven.ca/inbox/> .
GET 请求获取 Turtle 格式时发现 Inbox。关于如何进行发现,特别是面对未兼容本协议服务时的建议,请参阅Social Web Protocols。
在发现之后,希望发送通知的发送方必须通过对 Inbox URL 发起
POST 请求进行投递。发送方可期待收到 201 Created(并带
Location Link 头)或 202 Accepted 表示请求成功。
发送方可以使用 OPTIONS 请求询问服务器支持的 RDF 内容类型,并根据
Accept-Post 头 [Accept-Post] 序列化通知正文。否则,
POST 请求的正文必须为 JSON-LD 格式的负载,并带
Content-Type: application/ld+json。Content-Type
头可以带 profile URI [RFC6906]。
发送方可以为认证或鉴权目的附带额外 HTTP 头或内容,如 Authorization: Bearer XXX。
若发送方本地有无需认证的 localhost 服务,恶意脚本可能利用 Inbox 端点让发送方向本地自身发起任意 POST 请求。发送方不应向 localhost 或回环 IP 的 Inbox 发出 POST 请求。
发送示例请求
POST /inbox/ HTTP/1.1Host: example.orgContent-Type: application/ld+json;profile="https://www.w3.org/ns/activitystreams"Content-Language: en{"@context": "https://www.w3.org/ns/activitystreams","@id": "","@type": "Announce","actor": "https://rhiaro.co.uk/#me","object": "http://example.net/note","target": "http://example.org/article","updated": "2016-06-28T19:56:20.114Z"}
发送示例响应
HTTP/1.1 201 CreatedLocation: http://example.org/inbox/5c6ca040
POST 请求响应示例。接收方必须支持对
Inbox URL 的 GET 与 POST 请求。 在 LDP 术语中,Inbox 是一种Container。
收到 POST
请求,若通知资源处理成功,接收方必须返回 201 Created,并以
Location 头指明可获取该通知数据的 URL(参见消费者)。如异步排队处理,则必须返回 202 Accepted,并带响应正文说明请求状态。
如接收方对通知施加约束(见约束),未满足约束时建议拒绝处理并返回相应
4xx 错误码。
接收方必须接受正文为
JSON-LD、Content-Type: application/ld+json(可以带
profile URI [RFC6906])的通知。
接收方可以接受其他 RDF 内容类型(如
text/turtle、text/html),如支持建议在对 Inbox URL 的 OPTIONS 请求响应里,以
Accept-Post [Accept-Post]
头列出可接受的内容类型。
接收方示例 1:options 响应
OPTIONS /inbox/ HTTP/1.1Host: example.orgHTTP/1.1 200 OKAllow: GET, HEAD, OPTIONS, POSTAccept-Post: application/ld+json, text/turtle
OPTIONS 请求返回
Accept-Post 的回应。
接收方示例 2:post 响应
POST /inbox/ HTTP/1.1Host: example.orgContent-Type: application/ld+json;profile="https://www.w3.org/ns/activitystreams"Content-Language: en{"@context": "https://www.w3.org/ns/activitystreams","@id": "","@type": "Announce","actor": "https://rhiaro.co.uk/#me","object": "http://example.net/note","target": "http://example.org/article","updated": "2016-06-28T19:56:20.114Z"}HTTP/1.1 201 CreatedLocation: http://example.org/inbox/92d72f00
POST 请求响应,创建了一个通知。
对 Inbox 的 GET 请求成功时,必须返回带有通知 URI 列表的
HTTP 200 OK(根据请求者权限,也可能返回 4xx 错误码)。接收方可以仅列出该消费者可访问的通知 URI。 Inbox URL必须通过
http://www.w3.org/ns/ldp#contains 谓词指向这些通知。
每个通知必须为RDF 源。如返回非 RDF
资源,消费者可以忽略。请求通知 URI 的 GET 请求成功时,必须返回 HTTP 200 OK(若无权限,则为 4xx 错误码)。
所有资源必须支持 JSON-LD 内容类型,但客户端可用 Accept 头表明偏好其他内容类型(RFC7231 第 3.4 节 - 内容协商)。
如客户端未发送
Accept 头,服务器可返回 JSON-LD 或任何可靠表达同内容的信息(如 Turtle)。
Inbox 本身的其他描述可以一并返回(如约束)。
本规范未规定 Inbox 通知列表的分页机制。若需分页,可参考现有机制实现高效检索,如 Linked Data Platform Paging 1.0、Activity Streams 2.0 Collection。
接收方示例 3:get 响应
GET /inbox/ HTTP/1.1Host: example.orgAccept: application/ld+jsonAccept-Language: en-GB,en;q=0.8, en-US;q=0.6HTTP/1.1 200 OKContent-Type: application/ld+jsonContent-Language: en{"@context": "http://www.w3.org/ns/ldp","@id": "http://example.org/inbox/","contains": ["http://example.org/inbox/5c6ca040","http://example.org/inbox/92d72f00"]}
GET 请求,返回通知列表。接收方建议验证通知发送者。例如:
接收方建议使用约束过滤非预期通知被创建并暴露给 Inbox。
可考虑对 Inbox URL 实施访问控制,只允许可信发送者白名单写入。
消费者通过对 Inbox URL 发起 GET 请求获取通知 URI(如何获得 Inbox URL,参见发现)。
通知的 URI 必须可通过 Inbox URL 的 http://www.w3.org/ns/ldp#contains
谓词发现(见Inbox 内容示例)。
获取 Inbox 或单条通知时,消费者应当显式设置 Accept 头指出所偏好的内容类型(如
JSON-LD)。是否检索单独通知(数量、筛选等,如基于内容长度、时间戳),由消费者自行决定。
消费者可以为认证、鉴权目的添加额外 HTTP 头或内容。
消费者可以对负载执行进一步拉取或推断(例如解析通知引用的资源 URI,并检索其内容),也可以在使用前依据 Inbox 公布的约束校验通知。
获取到的通知 URI 的 RDF 声明,其 subject IRI 可能与请求 URI 不同。消费者不能假定通知含有以所请求 URI 为主体的三元组。如果通知正文中使用了相对 IRI,也要注意此情况。建议实现将通知 URI 视为包含负载 RDF 的图。
消费者需注意,任何内容都有可能被发布到 Inbox(取决于接收方所施空限制,本协议未定义具体机制),在使用通知数据时可能需要对内容真实性进行甄别。
消费者示例:获取通知
GET /inbox/14a792f0 HTTP/1.1Host: example.orgAccept: application/ld+json, text/turtle, application/xhtml+xml, text/htmlAccept-Language: en-GB,en;q=0.8, en-US;q=0.6HTTP/1.1 200 OKContent-Type: application/ld+json;profile="https://www.w3.org/ns/activitystreams"Content-Language: en{"@context": ["https://www.w3.org/ns/activitystreams",{ "@language": "en" }],"@id": "http://example.org/inbox/14a792f0","@type": "Announce","actor": {"@id": "http://csarven.ca/#i","name": "Sarven Capadisli"},"object": {"@context": "http://www.w3.org/ns/anno.jsonld","@id": "http://example.net/note","@type": "Annotation","motivation": "http://www.w3.org/ns/oa#assessing","rights": "http://creativecommons.org/licenses/by/4.0/"},"target": "http://example.org/article","updated": {"@type": "http://www.w3.org/2001/XMLSchema#dateTime","@value": "2016-06-28T19:56:20.114Z"}}
通知的负载必须为 JSON-LD,除非已与接收方协商使用其它 RDF 语法。为兼容各种用例,负载的具体词汇本规范不作限定。
本节为非规范性内容。
负载示例 1
{"@context": "http://schema.org/","@id": "http://example.net/note#foo","citation": { "@id": "http://example.org/article#results" }}
负载示例 2
{"@context": "https://www.w3.org/ns/activitystreams","@id": "","@type": "Announce","actor": "https://rhiaro.co.uk/#me","object": "http://example.net/note","target": "http://example.org/article","updated": "2016-06-28T19:56:20.114Z"}
负载示例 3
{"@context": { "pingback": "http://purl.org/net/pingback/" },"@id": "","@type": "pingback:Item","pingback:source": { "@id": "http://example.net/note#foo" },"pingback:target": { "@id": "http://example.org/article#results" }}
负载示例 4
{"@context": "http://schema.org/","@id": "","@type": "RsvpAction","event": { "@id": "http://example.org/event" },"agent": { "@id": "https://rhiaro.co.uk/#me" }}
通知可包含任意信息,包括对多个资源(有各自 URI)的引用,不一定指向某个特定外部资源或数据源。通常当消费者请求通知时,接收方应返回初始发送的所有三元组。
负载示例 5
{"@context": {"@language": "en","sioc": "http://rdfs.org/sioc/ns#","foaf": "http://xmlns.com/foaf/0.1/"},"@id": "","@type": "sioc:Comment","sioc:reply_of": { "@id": "http://example.org/article" },"sioc:created_at": {"@type": "http://www.w3.org/2001/XMLSchema#dateTime","@value": "2015-12-23T16:44:21Z"},"sioc:content": "This is a great article!","sioc:has_creator": {"@id": "http://example.org/profile","@type": "sioc:UserAccount","sioc:account_of": { "@id": "http://example.org/profile#alice" },"sioc:avatar": { "@id": "http://example.org/profile/avatar.png" },"foaf:name": "Alice"}}
负载示例 6
{"@context": [{"prov": "http://www.w3.org/ns/prov#"}],"@id": "http://example.org/activity/804c4e7efaa828e146b4ada1c805617ffbc79dc7","@type": "prov:Activity","http://www.w3.org/2000/01/rdf-schema#label": {"@language": "en","@value": "Make it so"},"prov:endedAtTime": {"@type": "http://www.w3.org/2001/XMLSchema#dateTime","@value": "2016-06-14T20:57:39.000Z"},"prov:generated": {"@id": "http://example.org/entity/804c4e7efaa828e146b4ada1c805617ffbc79dc7","@type": "prov:Entity","prov:specializationOf": { "@id": "http://example.org/entity/file" },"prov:wasGeneratedBy": {"@id": "http://example.org/activity/804c4e7efaa828e146b4ada1c805617ffbc79dc7"}},"prov:wasAssociatedWith": {"@id": "http://csarven.ca/#i","@type": "prov:Agent","http://xmlns.com/foaf/0.1/name": {"@language": "hy","@value": "Սարվէն Չափատիշլի"}}}
本节为非规范性内容。 与安全和隐私相关的规范性要求在规范中最相关的章节单独列出。
Inbox URL 可通过 HTTP Link 头或资源正文,rel 值为
http://www.w3.org/ns/ldp#constrainedBy 的声明,公开其约束(如 SHACL、Web Annotation
Protocol)。发送方应遵循约束定义,否则接收方可能拒绝通知并返回相应 4xx 错误码。
发布带有 Inbox(target)的资源的发布者,建议部署在可靠服务器。发布者必须认识到,第三方对头部或内容的访问可能导致通知被重定向。
本规范描述了消费者通过拉取方式从接收方读取通知,但有时消费者希望将新进通知或 Inbox 内容的变更主动推送给自己。同样,接收方也可能希望主动请求获取特定发送方的通知。这类订阅机制不属于本规范范围,但发送方、接收方和消费者可自行约定需要的方案。如需支持订阅,建议采用现有机制,如 ActivityPub、WebSub、WebSocket 协议、HTTP Web Push。
希望支持 Activity Streams 2.0 Core 的接收方实现,可参考 Social Web Protocols - Inbox Interop,了解 Content-Type 和词汇等价关系。
在联邦网络中建设国际化用户基础十分重要。一些 LDN 交互会返回包含自然语言文本的内容,例如 HTML
片段或摘要字段。在所有场景下为每条内容提供多语言版本不一定可行。鼓励实现提供机制来发现可用语言和/或协商返回语言,如通过 HTTP Accept-Language
头协商,为每次请求选择最合适的语言内容。
若接收方要求发送方或消费者认证,应在返回任何数据前先校验其凭据,包括错误码处理前。例如,若请求方尚未认证,接收方不应先检查 Inbox 是否存在后返回
404 Not Found。
涉及令牌传递的认证,必须通过 HTTPS 进行。
以下问题参考 安全与隐私自查问卷,涵盖本规范的安全与隐私注意事项。
本规范提升为建议标准(Proposed Recommendation)时,每项特性都有至少两个独立且可互操作的实现。每个特性由不同的产品实现。没有要求所有特性必须由单一产品实现。
在评估退出标准时,下列每项均视为一个特性:
Link 头广告资源的 Inbox。GET 请求返回 Inbox 通知列表,对单条通知的 GET 请求返回其内容。
我们要感谢并致谢以下人员对本规范的贡献:
本节为非规范性内容。
REC-ldn-20170502 ← PR-ldn-20170321 ← CR-ldn-20170223 ← CR-ldn-20161101 ← WD-ldn-20161011 ← WD-ldn-20160926 ← WD-ldn-20160913 ← WD-ldn-20160824 ← WD-ldn-20160726
1.1 社交网络工作组
LDN 是社交网络工作组发布的多个相关规范之一。对其他方案与互补协议感兴趣的实现者,建议首先阅读总览文档 Social Web Protocols。本规范各处会引用 Social Web Protocols 的具体章节,以突出扩展性或与其他协议互操作的要点。