Web of Things(WoT)物 描述 2.0

W3C 第一份公开 工作草案

关于本文档的更多详细信息
此版本:
https://www.w3.org/TR/2025/WD-wot-thing-description-2.0-20251104/
最新发布版本:
https://www.w3.org/TR/wot-thing-description-2.0/
最新编辑草案:
https://w3c.github.io/wot-thing-description/
历史:
https://www.w3.org/standards/history/wot-thing-description-2.0/
提交 历史
最新推荐标准:
https://www.w3.org/TR/2023/REC-wot-thing-description11-20231205/
编辑:
Ege KorkanSiemens AG
前任编辑:
Sebastian KaebischSiemens AG
Michael McCoolIntel Corp.
Takuki KamiyaFujitsu Research of America
Victor Charpenay (在 Siemens AG 任职时)
Matthias Kovatsch(在 Huawei 任职时)
反馈:
GitHub w3c/wot-thing-description拉取 请求 新议题开放 议题
public-wot-wg@w3.org,主题行请使用 [wot-thing-description-2.0] … 消息主题 …归档
贡献者
在 GitHub 仓库中
仓库
我们在 GitHub 上
提交 缺陷

摘要

本文档描述了 Web of Things(WoT)物 描述(TD)2.0 版的一个正式信息模型和 通用表示。物描述描述了的元数据和接口,其中是对物理 或虚拟实体的一种抽象,这些实体向 Web of Things 提供交互 并参与其中。物描述提供了一组基于小型词汇表的交互, 使集成各种设备以及让各种 应用实现互操作成为可能。物描述默认 编码为一种 JSON 格式,该格式也允许 JSON-LD 处理。后者提供了一个强大的基础,用于以机器可理解的 方式表示关于的知识。物描述实例可以由自身托管,或在存在 资源限制(例如,有限的内存空间)时,或在 Web of Things 兼容的旧式设备被改造为具有物 描述时,由外部托管。此外,本文档引入了物 模型,它允许作者仅描述物联网(IoT)实体的模型或类。 物模型可被视为物描述实例的模板, 但具有较少的约束,例如对特定 通信元数据没有要求或要求很少。

本规范延续了 [WOT-THING-DESCRIPTION11] 的工作,但不保证向后兼容。如果不 向后兼容,将为实现者提供具体指南,以迁移到 新版本。

本文档的状态

本节描述本文档在 发布时的状态。当前 W3C 出版物以及 本技术报告最新修订版的列表,可在 W3C 标准和草案 索引中找到。

本文档由 Web of Things Working Group 作为第一份公开工作草案发布,并使用推荐标准 轨道

作为第一份公开工作草案发布,并不意味着 得到 W3C 及其成员的认可。

这是一份草案文档,可能随时被更新、替换或 废弃。除作为进行中的工作外,不宜 引用本文档。

本文档由一个按照 W3C 专利政策运行的小组生成。 W3C 维护一份 与该小组可交付成果 相关的任何专利披露的公开列表;该页面还包含 披露专利的说明。实际知晓某项专利的个人, 若该个人认为该专利包含必要 权利要求,则必须按照 W3C 专利政策第 6 节 披露该信息。

本文档受2025 年 8 月 18 日 W3C 流程 文档管辖。

1. 引言

本节为非规范性内容。

1.1 物描述

WoT 物描述(TD)是 W3C Web of Things(WoT)中的核心构建块,并可被视为一个 的入口点(非常 类似于一个 Web 站点的 index.html)。一个 TD 实例有五个主要 组成部分:关于自身的文本元数据,一组交互可供性,用于 指示该如何 被使用;用于实现机器可理解性的、与交换的数据的 模式;用于提供必须为交互使用的安全 机制相关元数据的安全 定义;以及最后的 Web 链接, 用于表达与 Web 上其他或文档的任何正式或非正式关系。

W3C WoT 的 交互模型 定义了三类交互 可供性:属性(PropertyAffordance 类)可用于感知和控制参数, 例如获取当前值或设置操作 状态。动作(ActionAffordance 类) 对物理(因此耗时的) 过程调用进行建模,但也可用于抽象现有平台中类似 RPC 的调用。 事件(EventAffordance 类) 用于通信的推送模型,其中 通知、离散事件或值流被 异步发送给接收者。详情请参见 [wot-architecture11]。

一般而言,TD 为不同的 协议绑定 提供元数据,这些绑定由 URI 方案 [RFC3986] 标识(例如 httpcoap 等 [IANA-URI-SCHEMES]), 基于媒体类型 [RFC2046] 的内容类型(例如 application/jsonapplication/xmlapplication/cborapplication/exi 等 [IANA-MEDIA-TYPES]),以及安全 机制(用于认证、授权、 保密性等)。TD 实例的序列化 基于 JSON [RFC8259], 其中 JSON 名称引用 TD 词汇表中的术语,如 本规范文档所定义。此外,TD 的 JSON 序列化遵循 JSON-LD 1.1 [JSON-LD11] 的语法,以 支持扩展和丰富的语义处理。

示例 1 展示了一个 TD 实例,并通过描述一个标题为 MyLampThing 的灯, 用属性、动作和事件说明了交互 模型

从这个 TD 示例中,我们知道存在一个标题为 status属性可供性。 此外,示例还提供了信息,以 表明该属性可通过 HTTP 协议的(安全 形式)使用 GET 方法在 URI https://mylamp.example.com/status 处访问(在 forms 结构中通过 href 成员声明),并将返回一个基于字符串的 状态值。GET 方法的使用并未 显式声明,但它是本文档定义的 默认假设之一。

以类似方式,指定了一个动作 可供性,用于在 https://mylamp.example.com/toggle 资源上使用 POST 方法切换开关状态, 其中 POST 同样是调用 动作时的默认假设。

事件可供性 启用了一种机制,使消息能够由一个 异步发送。 在此处,可以通过在 https://mylamp.example.com/oh 上使用 HTTP 及其长轮询子协议, 获得对灯可能发生过热事件的 通知订阅。

此示例还指定了 basic 安全方案,需要用户名和密码才能 访问。请注意,安全方案首先在 securityDefinitions 中命名,然后通过 在 security 节中指定该名称来激活。结合 HTTP 协议的使用,此示例 演示了 HTTP Basic Authentication 的使用。 在顶层指定至少一个安全方案是 强制性的,并为每个资源给出默认访问要求。 不过,也可以按 form 指定安全方案, 在 form 层级给出的配置会覆盖 在 Thing 层级给出的配置,从而允许 指定细粒度访问控制。也可以使用 特殊的 nosec 安全方案来表示 未使用任何访问控制机制。后文将提供 更多示例。

物描述提供了在某个命名空间中添加 上下文定义的可能性。该机制可用于向 物描述实例的内容集成附加语义,前提是 形式化知识,例如某个特定应用领域的 逻辑规则,可以在给定命名空间下找到。 上下文信息还可以帮助指定 forms 字段中声明的底层通信 协议的某些配置和行为。示例 2 通过在 @context 中引入第二个定义来声明前缀 saref 指向 SAREF, 即 Smart Appliance Reference Ontology [SMARTM2M], 从而扩展示例 1 中的 TD 样例。 这个 IoT 本体包含被解释为语义 标签的术语,这些术语可被设置为 @type 字段的值,用于赋予及其交互 可供性以语义。在下面的示例中,被标注为 saref:LightSwitchstatus 属性被标注 为 saref:OnOffState,而 toggle 动作 被标注为 saref:ToggleCommand

某些 @context 内部的声明机制由 JSON-LD 指定。TD 实例 符合该规范的 1.1 版 [json-ld11]。 因此,TD 实例也可以作为 RDF 文档进行处理 (有关语义处理的详情,请参阅 附录 D. JSON-LD 上下文 用法以及命名空间 IRI 下的文档, 例如 https://www.w3.org/2019/wot/td)。

1.2 物模型

物 描述的主要意图之一,是向消费者提供与成功交互所 必需的全部细节。在某些 IoT 应用 场景中,一个包含完整细节的物描述, 例如带有通信元数据的描述,并非必要(例如,IoT 生态系统可能会隐式地单独处理通信), 或者可能尚不可用,因为新实体尚未 部署(例如,IP 地址尚未知晓)。有时,也 需要一种类定义,用于强制规定所有已创建 实例都应具备的能力定义(例如,新设备的大规模生产)。

为了解决上述场景或 其他场景,可以使用物 模型,它主要在属性动作和/或事件内提供数据模型 定义,并有可能被用作创建物描述 实例的模板。下面给出一个样例物模型, 它可被视为示例 1物 描述实例的模型。

示例 3:物模型 样例
{
    "@context": ["https://www.w3.org/ns/wot-next/td"],
    "@type": "tm:ThingModel",
    "title": "Lamp Thing Model",
    "properties": {
        "status": {
            "description": "current status of the lamp (on|off)",
            "type": "string",
            "readOnly": true
        }
    },
    "actions": {
        "toggle": {
            "description": "Turn the lamp on or off"
        }
    },
    "events": {
        "overheating": {
            "description": "Lamp reaches a critical temperature (overheating)",
            "data": {"type": "string"}
        }
    }
}

物 模型定义由 "@type": "tm:ThingModel" 标识。如示例所示,由于缺少 通信和安全元数据,它并不 提供关于单个实例的细节。本规范 给出了一种机制,用于从此类物模型定义派生有效的物 描述实例。 此外,还指定了其他设计概念,包括 如何覆盖、扩展和复用现有物模型 定义。

2. 一致性

除标记为非规范性的章节外,本规范中的所有编写 指南、图表、示例和注释均为非规范性内容。 本规范中的其他所有内容均为 规范性内容。

本文档中的关键词 MAYMUSTMUST NOTRECOMMENDEDSHOULDSHOULD NOT 在且仅在以此处所示的全大写形式出现时, 应按 BCP 14 [RFC2119] [RFC8174] 中的描述进行解释。

如果物描述实例遵循 5. TD 信息模型6. TD 表示格式 中关于物 描述序列化的规范性陈述,则该实例符合 本规范。

附录 B. 用于 TD 实例验证的 JSON Schema 中提供了一个用于验证物描述实例的 JSON Schema [JSON-SCHEMA]。

3. 术语

本节为非规范性内容。

基本的 WoT 术语,例如 消费者生产者物 描述TD)、部分 TD物 模型TM)、交互模型交互 可供性IoT 平台属性动作事件数据 模式内容类型协议 绑定服务体词汇表术语词汇表 术语WoT 接口,以及 WoT 运行时,定义于 WoT 架构规范 [wot-architecture11] 的第 3 节

此外,本规范引入以下 定义:

语义标签语义 标注
一种 JSON-LD 机制,用于将物描述 文档中的定义链接到(RDF)本体中的概念。这允许 物描述作者以标准化方式提供更多上下文并 表达领域知识。在物描述 文档中,这可以通过使用 @type 成员,以及通过使用带冒号 (:)的字符串前缀来实现。
TD 上下文扩展
一种用附加词汇表术语扩展物描述 的机制。它是语义 标注以及对协议绑定、安全方案和数据模式等 核心机制进行扩展的基础。
TD 信息 模型
一组由预定义词汇表构造而来的 定义,并对其施加约束,从而定义这些 词汇表的语义。类 定义通常以签名(一组 词汇表术语)以及 该签名上的函数来表示。 TD 信息模型还 包括默认值,其被定义为 上的一个全局函数。
TD 处理器
一种系统,能够将物 描述的某种内部表示 序列化为给定格式和/或从该格式反序列化。TD 处理器可以遵循验证步骤来检测 语义上不一致的物描述, 即无法满足 Thing 类的实例关系约束的物描述。 为此,TD 处理器 可以计算填入物描述的形式, 其中所有可能的默认值均被 赋值。TD 处理器通常是WoT 运行时的一个子系统。 TD 处理器的实现可以是 TD 生产者(能够序列化 为 TD 文档),也可以是 TD 消费者(能够从 TD 文档反序列化),或二者兼具。
TD 序列化TD 文档
物描述的文本或二进制表示, 可在服务体之间存储和交换。TD 序列化遵循给定的表示格式, 在通过网络交换时由媒体类型标识。 物描述的默认表示格式 是本规范所定义的基于 JSON 的格式。
TD 的 层级(包括 物层级可供性层级数据模式 层级Forms 层级
TD 或 TM 实例在给定层次 层级上的作用域。例如,TD 的根,其中定义了 @context 等术语,是物层级; forms 定义在可供性层级内; typemaximum 定义在 数据模式层级内;而 href 定义在 Forms 层级内。即使未定义,也可以使用其他层级, 例如 Links 层级。
绑定规范
绑定规范是一份文档,用于指定 某个协议、负载格式或二者的绑定。所有 绑定都遵循 WoT 绑定注册表 [WOT-BINDING-REGISTRY] 的规则。
绑定 实例
绑定实例是物描述中的一个 form 实例, 其中包含一个特定绑定,并实现一个 绑定 规范。例如,HTTP 绑定实例是一个 Form,其 hrefhttp://https:// 开头。

这些定义将在5.2 预备定义中进一步展开。

4. 命名空间

本规范5. TD 信息模型 中定义的TD 信息模型版本 由以下 IRI 标识:

https://www.w3.org/ns/wot-next/td

该 IRI [RFC3987], 同时也是一个 URI [RFC3986], 可被解引用以获取一个 JSON-LD 上下文文件 [json-ld11], 使TD 文档中的紧凑字符串能够展开为 基于完整 IRI 的词汇表 术语。不过,仅当把基于 JSON 的TD 文档转换为 RDF 时 才需要这种处理,而这是TD 处理器 实现的一项可选特性。

注意,该命名空间在规范达到推荐标准状态之前是临时的。 到那时,将分配一个永久命名空间。所有使用该 临时命名空间的文档都指向该规范 git 仓库的主分支,因此并不稳定。

在本规范中,词汇表术语总是 以其紧凑形式呈现。其展开形式可在它们所属 词汇表的命名空间 IRI 下访问。这些 命名空间遵循5.3 类 定义的结构。TD 信息模型中使用的每个 词汇表都有自己的命名空间 IRI,如下所示:

1 TD 中使用的 命名空间
词汇表 命名空间 IRI
核心 https://www.w3.org/ns/wot-next/td-ontology
数据模式 https://www.w3.org/ns/wot-next/json-schema-ontology
安全 https://www.w3.org/ns/wot-next/security-ontology
超媒体控件 https://www.w3.org/ns/wot-next/security-ontologyy

物模型定义额外使用的所有词汇表 具有以下命名空间 IRI:

2 TM 中使用的 命名空间
词汇表 命名空间 IRI
物模型 https://www.w3.org/ns/wot-next/tm-ontology

词汇表彼此独立。 它们可以在其他 W3C 规范中复用和扩展。对某个 词汇表设计的每一次破坏性变更,都需要 分配一个新的基于年份的命名空间 URI。请注意,为了 维护TD 信息模型的一般一致性, 相关的 JSON-LD 上下文文件会进行版本化,使得每个 版本都有自己的 URI(v1v1.1v2、……),以便同时标识非破坏性变更, 特别是新增术语

因为某个命名空间 IRI 下的词汇表 只能发生非破坏性变更,所以其内容可以被 安全地缓存或嵌入到应用中。在命名空间 IRI 下 暴露相对静态内容的一个优点,是可以 优化受限设备之间交换消息的负载大小。 它还避免了设备从私有网络访问公开可用 词汇表所导致的任何隐私泄露(另见12. 隐私考量)。

5. TD 信息模型

本节介绍TD 信息模型TD 信息模型 作为物描述及其序列化处理的概念基础; 序列化将在6. TD 表示 格式中单独描述。

5.1 概述

TD 信息模型构建在以下相互 独立的词汇表之上:

这些词汇表中的每一个本质上都是一组 术语, 可用于构建数据结构,并被解释为传统 面向对象意义上的对象。对象是类的 实例,并具有属性。在 W3C WoT 的语境中,它们 表示及其 交互 可供性。对象的形式化定义见 5.2 预备定义。随后在 5.3 类 定义中介绍TD 信息模型的主要元素。 当存在默认 值时,TD 中可以省略某些对象属性。 默认值列表见5.4 默认值定义

下面显示的 UML 图给出了 TD 信息模型的概述。 它将所有类表示为表,并将从类 Thing 开始的类之间存在的关联表示为有向 箭头。为了可读性,该图被拆分为四个部分, 每个部分对应四个基础词汇表之一。

TD 核心词汇表的 TD 信息模型 UML 图
1 TD 核心词汇表

数据模式词汇表的 TD 信息模型 UML 图
2 数据模式词汇表

WoT 安全词汇表的 TD 信息模型 UML 图
3 WoT 安全词汇表

超媒体控件词汇表的 TD 信息模型 UML 图
4 超媒体控件词汇表

5.2 预备定义

为了提供一个既能被基于树的文档上的简单规则 (即原始 JSON 处理)轻松处理,又能被丰富的 语义 Web 工具(即 JSON-LD 处理)轻松处理的模型,本文档定义以下形式化 预备内容,以相应地构造TD 信息模型

本节中的所有定义都涉及集合, 直观地说,集合是元素的集合,这些元素本身也可以 是集合。所有任意复杂的数据结构 都可以用集合来定义。特别地, 对象是一种 递归定义如下的数据结构:

虽然该定义并不阻止对象包含多个 具有相同名称的名称-值对,但本规范通常不 考虑这种情况。元素只以数字作为名称的 对象称为数组。类似地,元素只 以术语(且这些术语不属于任何 词汇表)作为名称的 对象 称为映射。出现在某个 映射中名称-值对里的所有 名称,都被假定在该映射的作用域内是唯一的

此外,对象 可以是某个的实例。由 词汇表术语表示的, 首先由一组称为 签名词汇表术语定义。 签名为空的 称为 简单类型

签名允许构造两个 进一步定义的函数:赋值函数类型函数赋值函数 接受该签名中的一个 词汇表术语作为输入,并返回 truefalse 作为输出。 直观地说,赋值函数 指示在实例化该时,签名中的某个元素是强制的还是 可选的。类型函数也 接受该签名中的一个 词汇表术语作为输入,并返回 另一个作为 输出。这些函数是部分函数:其定义域 限于所定义签名

基于这两个函数,可以为由一个 对象和一个组成的对定义 实例关系。 该关系被定义为需要满足的约束。也就是说, 如果同时满足以下两个约束,则一个对象是某个 的实例:

根据上述定义,一个对象将成为 每个简单 类型的实例,而不考虑其结构。因此, 为简单 类型引入了实例关系的另一个 定义:如果一个对象是具有给定词法形式的 术语 (例如,boolean 类型的 truefalseunsignedInt 类型的 123、……,等等),则它是一个 简单类型的实例。

此外,还可以从通用的映射数组结构派生出额外的 ,称为参数化 类。如果一个对象是某个 映射, 即参数化为某个映射类型的实例, 那么它就是一个映射,并且 它所包含的所有名称-值对中的值 都是该的实例。对于 数组也是如此。

最后,如果前一个的 每个实例也是后一个的实例, 则前一个类是后一个类的 子类

给定以上所有定义,TD 信息模型应被 理解为一组定义,其中包括 名称 (一个词汇表术语)、 签名(一组 词汇表术语)、 赋值函数, 以及类型 函数。这些 定义以表格形式提供于5.3 类定义中。对于每个表, 赋值列中的值“mandatory”(相应地,“optional”) 表示赋值函数 针对对应的词汇表术语返回 true(相应地,false)。

按照约定,简单类型由 以小写字母开头的名称表示。TD 信息模型 引用了 XML Schema [XMLSCHEMA11-2-20120405] 中定义的以下 简单 类型stringanyURIdateTimeintegerunsignedIntdoubleboolean。它们的定义(即其 词法形式的规范)不属于TD 信息模型的范围。

此外,TD 信息模型定义了一个 作用于词汇表术语对的全局函数。 该函数接受一个名称 和另一个词汇表术语作为输入,并返回一个 对象。 如果返回的对象 不同于 null,它表示输入 的实例中输入 词汇表术语上某个赋值的 默认值。该函数允许 放宽上述关于赋值函数的约束: 如果一个对象 包含所有强制赋值,或者缺失的赋值存在 默认值, 则它是一个的实例。 所有默认值都列于 5.4 默认值 定义的表中。在5.3 类定义的每个表中,如果 TD 信息 模型中对应的词汇表术语组合可用 默认值,则赋值 列包含值“with default”。

此处引入的形式化并不考虑作为抽象数据结构的 对象与物理世界对象(例如 )之间可能存在的关系。然而,已注意到 可以将TD 信息模型中涉及的所有词汇表术语 重新解释为 RDF 资源,从而将它们集成到一个更大的 物理世界模型(本体)中。有关语义处理的详情, 请参阅 D. JSON-LD 上下文用法以及 命名空间 IRI 下的 文档,例如 https://www.w3.org/2019/wot/td

5.3 类定义

一个 TD 处理器MUST 满足 实例化约束, 这些约束适用于 中定义于 5.3.1 核心词汇 定义5.3.2 数据模式 词汇定义5.3.3 安全词汇 定义,以及 5.3.4 超媒体控件 词汇定义中的所有类。

尤其需要注意,所有词汇表术语和值 都区分大小写。信息模型的序列化 也是如此(第 6. TD 表示格式节)。

5.3.1 核心词汇 定义

5.3.1.1 Thing

物理实体或虚拟实体的一种抽象,其 元数据和接口由 WoT 物 描述来描述;其中虚拟实体是 一个或多个物的组合。

3 物层级中的词汇表 术语
词汇表术语 描述 赋值 类型
@context JSON-LD 关键字,用于定义称为术语的 简写名称,这些名称会在整个 TD 文档中使用。 强制 anyURI数组
@type JSON-LD 关键字,用于用语义标签 (或类型)标记对象。 可选 string 或由 数组 组成的 string
id 以 URI 形式给出的物标识符 [RFC3986] (例如稳定 URI、临时且可变的 URI、带有 本地 IP 地址的 URI、URN 等)。 可选 anyURI
title 基于默认语言提供人类可读标题 (例如显示用于 UI 表示的文本)。 强制 string
titles 提供多语言人类可读标题 (例如以不同语言显示用于 UI 表示的文本)。 另见 MultiLanguage 可选 映射,其值为 MultiLanguage
description 基于默认语言提供附加(人类可读) 信息。 可选 string
descriptions 可用于支持不同语言中的(人类可读) 信息。另见 MultiLanguage 可选 映射,其值为 MultiLanguage
version 提供版本信息。 可选 VersionInfo
created 提供 TD 实例创建时间的信息。 可选 dateTime
modified 提供 TD 实例最后修改时间的信息。 可选 dateTime
support 以 URI 方案形式提供关于 TD 维护者的信息 (例如 mailto [RFC6068]、 tel [RFC3966]、 https [RFC9112])。 可选 anyURI
base 定义基础 URI,用于整个 TD 文档中的所有 相对 URI 引用。在 TD 实例中,所有相对 URI 都使用 [RFC3986] 中定义的算法,相对于基础 URI 解析。

base 不影响 @context 中使用的 URI, 也不影响在对 TD 实例应用语义处理时相关的 Linked Data [LINKED-DATA] 图中使用的 IRI。
可选 anyURI
properties 物的所有基于属性的交互 可供性 可选 映射,其值为 PropertyAffordance
actions 物的所有基于动作的交互 可供性 可选 映射,其值为 ActionAffordance
events 物的所有基于事件的交互 可供性 可选 映射,其值为 EventAffordance
forms 描述如何执行操作的一组 form 超媒体控件。 Forms 是协议绑定的序列化。物 层级 forms 用于描述一组交互可供性的端点。 可选 数组,其元素为 Form
security 一组安全定义名称,从 securityDefinitions 中定义的名称中选取。 要访问资源,必须全部满足这些安全定义。 强制 string 或由 数组 组成的 string
securityDefinitions 一组具名安全配置 (仅为定义)。除非名称被用于 security 名称-值对中,否则并不会实际应用。 强制 映射,其值为 SecurityScheme
profile 指示此物描述及相应的 物实现所遵循的 WoT Profile 机制。 可选 anyURI 或由 数组 组成的 anyURI
schemaDefinitions 一组具名数据模式。用于 AdditionalExpectedResponse 对象内的 schema 名称-值对。 可选 映射,其值为 DataSchema
uriVariables 按照 [RFC6570] 定义 URI 模板变量, 其集合基于 DataSchema 声明。物 层级 uriVariables 可用于物 层级 forms 或交互可供性中。 各个变量的 DataSchema 不能是 ObjectSchema 或 ArraySchema,因为在执行操作时, 每个变量都需要在 href 内被序列化为字符串。 如果同一个变量同时在物层级 uriVariables 和交互 可供性层级中声明,则交互可供性 层级变量优先。 可选 映射,其值为 DataSchema

以下关于 @context URL 规则的列表项将经历重大 变更。

对于 @context,为 物描述 实例定义了以下规则:

  • @context 名称-值对 MUST 包含 anyURI https://www.w3.org/2022/wot/td/v1.1, 以便将该文档标识为 TD 1.1,从而允许 消费者使用新 引入的术语。
  • 当可能存在 TD 1.0 消费者时,anyURI https://www.w3.org/2019/wot/td/v1 MUST 是第一项,而 https://www.w3.org/2022/wot/td/v1.1 MUST 是第二 项。
  • TD 1.1 消费者 MUST 接受满足 W3C WoT Thing Description 1.0 [wot-thing-description10] 规范的 TD。
  • @context 是一个数组时,anyURI https://www.w3.org/2022/wot/td/v1.1 MAY 后面可以 以任意顺序跟随类型为 anyURI 或类型为映射的元素,同时 RECOMMENDED 只包含 一个映射, 其中包含 @context 数组中的所有名称-值对。
  • 映射包含在 @context 数组中时,MAY 包含名称-值 对,其中 值是类型为 anyURI 的命名空间标识符, 名称是术语或表示该 命名空间的前缀。
  • 包含在 @context 数组中的一个映射 SHOULD 包含一个名称-值对, 该名称-值对定义物描述的默认语言, 其中名称是术语 @language, 值是 [BCP47] 所定义的格式良好的语言标签 (例如 ende-ATgsw-CHzh-Hanszh-Hant-HKsl-nedis)。

为了确定物描述物 模型实例中所有人类可读文本的基本方向, 本规范建议在没有内置机制可用于关联基本方向 元数据时,遵循 [STRING-META] 关于 字符串特定方向信息的指南。

TD 处理器在处理双向文本时应注意某些特殊情况。 TD 处理器 SHOULD 在向用户呈现字符串时注意使用 bidi 隔离, 尤其是在嵌入周围文本时(例如 Web 用户 界面)。混合方向文本可以出现在任何 语言中,即使该语言已被正确 标识。

TD 生产者 SHOULD 尝试以一种能被 朴素用户代理成功显示的方式提供混合方向 字符串。例如,如果一个 RTL 字符串 以 LTR 片段开头(例如数字或拉丁文字中的品牌或 商品名称),则在字符串开头包含一个 RLM 字符, 或者用 bidi 控制符包裹相反方向的片段, 可以帮助正确显示。

Strings on the Web: Language and Direction Metadata [string-meta] 提供了一些指导,并说明了使用双向文本时的 若干陷阱。

除了在 propertiesactionsevents 映射中 显式提供的交互 可供性之外,一个还可以 提供元交互,这些元交互由其可选 forms 数组中的 Form 实例表示。当一个实例的 forms 数组包含 Form 实例时,它 MUST 包含 op 成员, 且赋给名称 op 的字符串值, 无论是直接给出还是在数组中给出,MUST 是以下 操作类型之一:readallpropertieswriteallpropertiesreadmultiplepropertieswritemultiplepropertiesobserveallpropertiesunobserveallpropertiesqueryallactionssubscribealleventsunsubscribeallevents(参见示例, 了解在物实例中使用 form 的情况。)

每个属性元交互的数据模式通过组合每个 PropertyAffordance 实例的数据模式来构造, 并放入单个 ObjectSchema 实例中;其中 ObjectSchema 实例的 properties 映射包含每个 PropertyAffordances 的数据模式,这些 数据模式由对应 PropertyAffordances 实例的名称标识。

如果未另行指定(例如通过 TD 上下文 扩展), readmultipleproperties 操作的请求数据是一个 数组,其中包含 预期的 PropertyAffordances 实例 名称,并会被序列化为 Form 实例指定的内容类型。

5.3.1.2 InteractionAffordance

物的元数据,向 消费者展示可能的选择,从而 提示消费者如何与 物交互。潜在可供性有许多类型, 但 W3C WoT 定义了三类交互可供性: 属性、动作和事件。

4 InteractionAffordance 层级中的词汇表术语
词汇表术语 描述 赋值 类型
@type JSON-LD 关键字,用于用语义标签 (或类型)标记对象。 可选 string 或由 数组 组成的 string
title 基于默认语言提供人类可读标题 (例如显示用于 UI 表示的文本)。 可选 string
titles 提供多语言人类可读标题 (例如以不同语言显示用于 UI 表示的文本)。 另见 MultiLanguage 可选 映射,其值为 MultiLanguage
description 基于默认语言提供附加(人类可读) 信息。 可选 string
descriptions 可用于支持不同语言中的(人类可读) 信息。另见 MultiLanguage 可选 映射,其值为 MultiLanguage
forms 描述如何执行操作的一组 form 超媒体控件。 Forms 是协议绑定的序列化。该数组 不能为空。 强制 数组,其元素为 Form
uriVariables 按照 [RFC6570] 定义 URI 模板变量, 其集合基于 DataSchema 声明。各个 变量的 DataSchema 不能是 ObjectSchema 或 ArraySchema,因为执行操作时,每个变量都需要 在 href 内被序列化为字符串。 如果同一变量同时在物层级 uriVariables和交互可供性层级中声明, 则交互可供性层级变量优先。 可选 映射,其值为 DataSchema

InteractionAffordance 类具有以下 子类:

5.3.1.3 PropertyAffordance

一种暴露物状态的交互可供性。 该状态随后可以被检索(读取)和/或 更新(写入)。物也可以选择通过在发生 变化后推送新状态,使属性可被观察。

5 PropertyAffordance 层级中的词汇表术语
词汇表术语 描述 赋值 类型
observable 一个提示,用于指示托管 物的服务体和中介是否应提供一个 支持该属性的 observepropertyunobserveproperty 操作的 协议绑定。 有默认值 boolean

Property 实例也是 DataSchema 类的实例。因此,它可以包含 typeunitreadOnlywriteOnly 成员,以及其他成员。

PropertyAffordanceInteractionAffordance DataSchema 子类当 Form 实例位于 PropertyAffordance 实例内部时,赋给 op 的值 MUSTreadpropertywritepropertyobservepropertyunobserveproperty 之一,或是包含这些术语组合的 数组

良好实践是,每个 observeproperty 都有一个对应的 unobserveproperty,除非协议 支持隐式取消订阅机制(例如用于检测连接丢失的 heartbeat)。

观察机制取决于底层协议或子协议。 尽管如此,并不能保证在启动订阅后 会提供当前属性值。 因此,可能需要在订阅之前/之后读取当前 属性值, 以获得第一个值。

5.3.1.4 ActionAffordance

一种交互可供性,允许调用物的 某个函数,该函数会操纵状态(例如打开或关闭灯) 或触发物上的一个过程(例如随时间调暗灯)。

6 ActionAffordance 层级中的词汇表术语
词汇表术语 描述 赋值 类型
input 用于定义动作的输入数据模式。 可选 DataSchema
output 用于定义动作的输出数据模式。 可选 DataSchema
safe 标示动作是否安全(=true)。 用于标示调用动作时没有内部状态 (参见资源状态)发生改变。在这种情况下, 响应可以被缓存,例如。 有默认值 boolean
idempotent 指示动作是否幂等 (=true)。说明该动作在存在相同输入的情况下, 是否可以被重复调用并得到相同结果。 有默认值 boolean
synchronous 指示该动作是否同步 (=true)。同步动作意味着动作的 响应包含关于动作结果的全部信息, 且不需要再查询动作状态。 缺少该关键字意味着不能对该动作的 同步性作出声明。 可选 boolean

ActionAffordanceInteractionAffordance 子类当 Form 实例位于 ActionAffordance 实例内部时,赋给 op 的值 MUSTinvokeactionqueryactioncancelaction 之一,或是 包含这些术语组合的 数组

5.3.1.5 EventAffordance

一种交互可供性,用于描述一个事件 源,它会向 消费者异步推送事件数据(例如过热 警报)。

7 EventAffordance 层级中的词汇表术语
词汇表术语 描述 赋值 类型
subscription 定义订阅时需要传递的数据, 例如用于设置 Webhooks 的过滤器或消息格式。 可选 DataSchema
data 定义由物推送的事件实例 消息的数据模式。 可选 DataSchema
dataResponse 定义消费者响应数据消息时发送的 事件响应消息的数据模式。 可选 DataSchema
cancellation 定义取消订阅时需要传递的任何数据, 例如用于移除 Webhook 的特定消息。 可选 DataSchema

EventAffordanceInteractionAffordance 子类当 Form 实例位于 EventAffordance 实例内部时,赋给 op 的值 MUSTsubscribeeventunsubscribeevent,或在一个 数组中同时包含这两个术语。

良好实践是,每个 subscribeevent 都有一个对应的 unsubscribeevent,除非协议 支持隐式取消订阅机制(例如用于检测连接丢失的 heartbeat)。

EventAffordances 与可观察的 PropertyAffordances 类似,因为物自身会 将状态变化告知感兴趣的消费者。 但是,EventAffordances 的一个主要区别是, 相关资源的每一次变化并不一定需要 触发发出事件消息,例如数值的临界 阈值。此外, EventAffordances 允许通过定义 subscriptiondataResponsecancellation DataSchema 定义来实现更复杂的订阅和 取消订阅机制。不过,并非所有 协议都可能支持这些更高级的机制, 因此在某些场景中,事件可能与可观察的 PropertyAffordances 非常相似。在这些 情况下,应根据底层资源的语义来 在属性和事件之间选择用哪一个来建模 可供性;例如,如果该可供性的状态也预期 由消费者读取或写入,那么属性很可能是 合适的选择。

5.3.1.6 VersionInfo

物的元数据,用于提供关于 TD 文档的版本信息。 如有需要,可通过 TD 上下文扩展机制扩展附加版本信息,例如固件和硬件版本 (TD 命名空间之外的术语定义)。

8 VersionInfo 层级中的词汇表术语
词汇表术语 描述 赋值 类型
instance 提供此 TD 的版本指示符。 强制 string
model 提供底层 TM 的版本指示符。 可选 string

建议 VersionInfo 中的 instancesmodel 的值遵循语义化 版本模式,其中由点分隔的三个数字序列 分别表示主版本、次版本和补丁版本。 详情见 [SEMVER]。

5.3.1.7 MultiLanguage

一个映射, 提供一组以 [BCP47] 中描述的 语言标签标识的不同语言的人类可读文本。请参阅 6.3.2 人类可读 元数据,了解该容器在 物描述实例中的示例用法。

MultiLanguage 映射的每个名称 MUST 是 [BCP47] 中定义的语言标签。 MultiLanguage 映射的每个值 MUSTstring 类型。

5.3.2 数据模式词汇 定义

数据模式是一种用于表示数据格式中所含数据的 抽象记法。

数据模式词汇定义反映了 JSON Schema [JSON-SCHEMA] 所定义术语的一个非常常见的子集。 用于 JSON Schema draft 7 的 JSON Schema [JSON-SCHEMA] 处理器可以消费数据模式。需要注意的是, 物描述实例中的数据模式定义并不限于 这个已定义子集,并且可以通过 TD 上下文扩展 使用 JSON Schema 中发现的附加术语, 如 7. TD 上下文扩展所述;否则这些 术语会被TD 处理器 在语义上忽略(有关语义处理的详情,请参阅 D. JSON-LD 上下文用法 以及命名空间 IRI 下的 文档,例如 https://www.w3.org/2019/wot/td)。

在 TD 中,具体数据格式通过 Forms (见 5.3.4.2 Form) 使用内容 类型来指定。当 Form 实例中的内容类型值为 application/json 时,数据模式 可以由 JSON Schema 处理器直接处理。 否则,Web of Things(WoT)绑定注册表 [WOT-BINDING-REGISTRY] 中的条目定义了从数据模式到其他 内容类型(如 XML [xml])的可用映射。 如果 Form 实例中的内容类型不是 application/json,且没有为该内容类型 定义映射,那么为该内容类型指定数据模式并 没有意义。

下表包含 MAY 使用数据模式来描述其负载 结构的内容类型。

9 可以使用数据 模式的内容类型
格式 内容类型
JSON/CBOR application/json
application/ld+json
application/senml+json
application/cbor
application/senml+cbor
XML/EXI application/xml
application/senml+xml
application/exi
application/senml-exi
5.3.2.1 DataSchema

描述所用数据格式的元数据。它可用于 验证。

10 DataSchema 层级中的词汇表术语
词汇表术语 描述 赋值 类型
@type JSON-LD 关键字,用于用语义标签 (或类型)标记对象 可选 string 或由 数组 组成的 string
title 基于默认语言提供人类可读标题 (例如显示用于 UI 表示的文本)。 可选 string
titles 提供多语言人类可读标题 (例如以不同语言显示用于 UI 表示的文本)。 另见 MultiLanguage 可选 映射,其值为 MultiLanguage
description 基于默认语言提供附加(人类可读) 信息。 可选 string
descriptions 可用于支持不同语言中的(人类可读) 信息。另见 MultiLanguage 可选 映射,其值为 MultiLanguage
const 提供一个常量值。 可选 任意类型
default 提供默认值。该值 SHOULD 通过其所在 数据 模式的验证。 可选 任意类型
unit 提供单位信息,例如用于国际科学、 工程和商业。为保持唯一性,建议 unit 的值指向一个语义 定义(另见 语义 标注一节)。 可选 string
oneOf 用于确保数据对数组中指定的 某一个模式有效。这可用于描述多个输入或输出 模式。 可选 数组,其元素为 DataSchema
enum 以数组形式提供的一组受限 值。 可选 数组,其元素为任意类型
readOnly 布尔值,用作提示,指示 属性交互/值是否为只读 (=true)或否(=false)。 有默认值 boolean
writeOnly 布尔值,用作提示,指示 属性交互/值是否为只写 (=true)或否(=false)。 有默认值 boolean
format 允许基于格式模式进行验证, 例如 "date-time"、"email"、"uri" 等。(另见 下文。) 可选 string
type 赋予与 JSON Schema 兼容的基于 JSON 的数据类型 (boolean、integer、number、 string、object、array 或 null 之一)。 可选 anyURI(以下之一: objectarraystringnumberintegerbooleannull

DataSchema 类具有以下 子类:

format 字符串值来自一组 固定的值,以及 [JSON-SCHEMA] 中定义的相应格式规则 (尤其是第 7.3 节“已定义格式”)。服务体 MAY 使用 format 值 相应执行附加验证。 当赋给 format 的值不在已知值集合中时, 这样的验证 SHOULD 成功。

类型为 any type 的词汇表术语 (例如 constdefault)遵循 与 JSON Schema 兼容的数据类型(boolean、integer、 number、string、object、array 或 null)。

format 术语并未被 JSON Schema 工具 广泛实现。此外,术语 format 正在 JSON Schema 标准化社区中讨论,未来 JSON Schema 版本中可能会被另一种机制替代或移除。

5.3.2.2 ArraySchema

描述类型为数组的数据的元数据。 此子类DataSchema 实例中赋给 type 的值 array 表示。

11 ArraySchema 层级中的词汇表术语
词汇表术语 描述 赋值 类型
items 用于定义数组的特征。 可选 DataSchema 或由 数组 组成的 DataSchema
minItems 定义数组中必须包含的最小 项数。 可选 unsignedInt
maxItems 定义数组中必须包含的最大 项数。 可选 unsignedInt
5.3.2.3 BooleanSchema

描述类型为 boolean 的数据的元数据。 此子类DataSchema 实例中赋给 type 的值 boolean 表示。

5.3.2.4 NumberSchema

描述类型为 number 的数据的元数据。 此子类DataSchema 实例中赋给 type 的值 number 表示。

12 NumberSchema 层级中的词汇表术语
词汇表术语 描述 赋值 类型
minimum 指定一个最小数值,表示 包含式下限。仅适用于 相关的 number 或 integer 类型。 可选 double
exclusiveMinimum 指定一个最小数值,表示 排除式下限。仅适用于 相关的 number 或 integer 类型。 可选 double
maximum 指定一个最大数值,表示 包含式上限。仅适用于 相关的 number 或 integer 类型。 可选 double
exclusiveMaximum 指定一个最大数值,表示 排除式上限。仅适用于 相关的 number 或 integer 类型。 可选 double
multipleOf 指定 multipleOf 值数。 该值必须严格大于 0。仅适用于 相关的 number 或 integer 类型。 可选 double
5.3.2.5 IntegerSchema

描述类型为 integer 的数据的元数据。 此子类DataSchema 实例中赋给 type 的值 integer 表示。

13 IntegerSchema 层级中的词汇表术语
词汇表术语 描述 赋值 类型
minimum 指定一个最小数值,表示 包含式下限。仅适用于 相关的 number 或 integer 类型。 可选 integer
exclusiveMinimum 指定一个最小数值,表示 排除式下限。仅适用于 相关的 number 或 integer 类型。 可选 integer
maximum 指定一个最大数值,表示 包含式上限。仅适用于 相关的 number 或 integer 类型。 可选 integer
exclusiveMaximum 指定一个最大数值,表示 排除式上限。仅适用于 相关的 number 或 integer 类型。 可选 integer
multipleOf 指定 multipleOf 值数。 该值必须严格大于 0。仅适用于 相关的 number 或 integer 类型。 可选 integer
5.3.2.6 ObjectSchema

描述类型为对象的数据的元数据。 此子类DataSchema 实例中赋给 type 的值 object 表示。

14 ObjectSchema 层级中的词汇表术语
词汇表术语 描述 赋值 类型
properties 嵌套的数据模式定义。 可选 映射,其值为 DataSchema
required 定义 object 类型的哪些成员是 强制的,即将要发送的负载中哪些成员是强制的 (例如 invokeaction 的输入、 writeproperty),以及正在接收的负载中 哪些成员将被确实交付(例如 invokeaction 的输出、 readproperty 可选 数组,其元素为 string
5.3.2.7 StringSchema

描述类型为 string 的数据的元数据。 此子类DataSchema 实例中赋给 type 的值 string 表示。

15 StringSchema 层级中的词汇表术语
词汇表术语 描述 赋值 类型
minLength 指定字符串的最小长度。仅适用于 相关的 string 类型。 可选 unsignedInt
maxLength 指定字符串的最大长度。仅适用于 相关的 string 类型。 可选 unsignedInt
pattern 提供一个正则表达式,用于表示 字符串值的约束。该正则 表达式必须遵循 [ECMA-262] 方言。 可选 string
contentEncoding 指定用于存储内容的编码, 如 [RFC2045] (第 6.1 节)和 [RFC4648] 所指定。 可选 string(例如 7bit8bitbinaryquoted-printablebase16base32base64
contentMediaType 指定字符串值内容的 MIME 类型, 如 [RFC2046] 所述。 可选 string(例如 image/pngaudio/mpeg

字符串的长度(即 minLengthmaxLength) 被定义为 Unicode 码点的数量,如 [RFC8259] 所定义。注意,某些用户感知字符由 多个 Unicode 码点组成。任意 索引值可能不会落在这些字素 边界上,因此按照 maxLength 截断可能会改变字符串的外观或 含义。

5.3.2.8 NullSchema

描述类型为 null 的数据的元数据。 该子类由 DataSchema 实例中赋给 type 的值 null 表示。该子类只描述一个可接受 值,即 null。需要注意的是, null 并不表示没有 值。它类似于 JavaScript 中的 null、 Python 中的 None、 Java 中的 null 和 Ruby 编程语言中的 nil。它可作为 oneOf 声明的一部分使用,在其中用于 表示该数据也可以是 null

5.3.3 安全词汇 定义

本规范提供一组 成熟的安全机制,这些机制要么直接 内置于可作为 W3C WoT 协议 绑定的协议中,要么广泛用于 这些协议。当前的 HTTP 安全 方案集合部分基于 OpenAPI 3.0.1(另见 [OPENAPI])。 但是,虽然本规范给出的 HTTP 安全方案、 词汇表和语法 与 OpenAPI 有许多相似之处, 它们并不兼容。

一般而言,安全方案需要某种形式的安全 传输才能有效,例如 TLS 或 DTLS。 关于使用安全传输的要求见本文档 第 11. 安全 考量节,以及 [wot-architecture11] 的安全 考量一节。

5.3.3.1 SecurityScheme

描述安全机制配置的元数据。 赋给名称 scheme 的值 MUST 定义在 物描述中包含的 词汇表内, 可以是在 § 5. TD 信息模型中定义的标准 词汇表, 也可以是在TD 上下文 扩展中。

对于所有安全方案,任何 密钥、密码或其他直接提供访问能力的敏感信息 MUST NOT 存储在 TD 中,而应通过其他机制 在带外共享和存储。TD 的目的 是在且仅在消费者已经获得授权时, 描述如何访问某个物,而并非用于 授予该授权。

TD 中使用的每个安全方案对象定义了一组 在授予访问前必须满足的要求。 当一个安全方案的所有要求都被满足时,我们称其 已满足。在某些情况下,必须先满足 多个安全方案的要求,才能授予访问。

安全方案通常可能需要附加的 认证参数,例如密码或密钥。 这些信息的位置由与名称 in 关联的值指示, 通常还会结合与 name 关联的值。与 in 关联的值可以取以下值之一:

header
参数将放在协议提供的 header 中, header 的名称由 name 的值提供。
query
参数将作为查询参数附加到 URI, 查询参数的名称由 name 提供。
body
参数将放在请求负载的 body 中, 使用的数据模式元素由 name 提供。 当在 body 安全信息位置的上下文中使用时, name 的值 MUST 采用 JSON 指针 [RFC6901] 的形式,并相对于其所用于的每个交互的输入 DataSchema 的根。由于该值不是片段 标识符,也不是相对于 TD 的根,而是相对于 安全方案所绑定的任何数据模式,因此该值不应以 # 开头;它是一个“纯”JSON 指针。 由于该值不是片段标识符,也不需要对特殊字符 进行 URL 编码。目标元素可能已经存在于 所引用对象或数组模式中的指定位置,也可能不存在 (因此该机制不适用于简单类型)。如果不存在, 将插入该元素。这避免了在每个交互的数据 模式中重复定义。body 定位器中指示的 JSON 指针所指示的数据模式元素 在所指示的模式中尚不存在时,MUST 能够 在指针所指示的位置插入该 元素。 body 定位器中使用的 JSON 指针 MAY 使用 "-" 字符来指示不存在的数组元素,当需要 在现有数组最后一个元素之后插入元素时。 body 安全信息位置所引用(或创建)的元素 MUST 是必需的,并且类型为 "string"。如果未给出 name,则假定整个 body 都将用作安全 参数。
cookie
参数存储在由 name 的值标识的 cookie 中。
uri
参数嵌入在 URI 本身中, 该 URI 在相关交互中使用由 name 的值定义的 URI 模板变量进行编码。这比 query 机制更通用,但也更复杂。 仅当 query 不适用时, uriSHOULD 被 指定为安全方案中名称 in 的值。 在使用 uri 作为 in 值的安全方案的交互中提供的 URI MUST 是包含已定义变量的 URI 模板。
auto
位置作为协议的一部分确定, 或通过协商确定。如果 SecuritySchemein 字段设置为 auto 值,则 name 字段 SHOULD NOT 被设置。在这种情况下, SecurityScheme 的应用受给定协议的相应规范约束 (例如在使用 HTTP 的 BasicSecurityScheme 时为 [RFC8288])。

如果某个安全方案需要多个参数, 请为每个参数重复安全方案定义,并使用 combo 安全方案和 allOf 将其组合。 在某些情况下,参数实际上可能并非秘密,但用户可能 希望将其排除在 TD 之外以帮助保护隐私。 一个例子是,某些安全机制同时需要 客户端标识符和密钥。理论上,客户端 标识符是公开的;然而它可能难以更新并 带来跟踪风险。在这种情况下,可将其作为 附加安全参数提供,使其不出现在 TD 中。

SecurityScheme 中声明的 URI 变量名称 MUST 与 TD 中声明的所有其他 URI 变量不同。

16 SecurityScheme 层级中的词汇表术语
词汇表术语 描述 赋值 类型
@type JSON-LD 关键字,用于用语义标签 (或类型)标记对象。 可选 string 或由 数组 组成的 string
description 基于默认语言提供附加(人类可读) 信息。 可选 string
descriptions 可用于支持不同语言中的(人类可读) 信息。另见 MultiLanguage 可选 映射,其值为 MultiLanguage
proxy 该安全配置为其提供访问的代理服务器 URI。 如果未给出,则相应的安全配置用于 端点。 可选 anyURI
scheme 所配置安全机制的标识。 强制 string(例如 noseccombobasicdigestbearerpskoauth2apikeyauto

SecurityScheme 类具有以下 子类:

5.3.3.2 NoSecurityScheme

一种安全配置,对应于由 词汇表术语 nosec 标识(即 "scheme": "nosec"),表示访问资源不需要认证或 其他机制。

5.3.3.3 AutoSecurityScheme

一种由术语 auto 标识的自动认证安全配置 (即 "scheme": "auto")。该方案表示 安全参数将在运行时由底层协议协商, 并受该协议相应规范的约束(例如在使用 HTTP 时 Basic Authentication 的 [RFC8288])。

5.3.3.4 ComboSecurityScheme

词汇表术语 combo 标识的其他安全方案的组合 (即 "scheme": "combo")。该方案的元素定义了 如何组合 securityDefinitions 中定义的其他具名方案(包括其他 ComboSecurityScheme 定义),以创建新的方案 定义。必须且只能包含 oneOfallOf 词汇表术语之一。只有可以一起使用的安全方案定义 才能用 allOf 组合。例如,一般不可能 使用 allOf 将不同的 OAuth 2.0 流组合在一起, 除非一个适用于代理而另一个适用于端点。 注意,当多个具名安全方案定义列在 security 字段中时,其语义与 allOf 组合相同(并具有相同的 可允许组合限制)。oneOf 组合等价于 在其他方面相同的 forms 上使用不同的安全方案。 从这个意义上说,oneOf 方案并非必要特性, 但它可以避免此类情况下的冗余。

17 ComboSecurityScheme 层级中的词汇表术语
词汇表术语 描述 赋值 类型
oneOf 由两个或更多字符串组成的数组,用于标识其他 具名安全方案定义;其中任意一个 被满足时即可允许访问。只能选择其中一个 使用。 强制 数组,其元素为 string
allOf 由两个或更多字符串组成的数组,用于标识其他 具名安全方案定义;这些定义必须全部 被满足才能访问。 强制 数组,其元素为 string
5.3.3.5 BasicSecurityScheme

Basic Authentication [RFC7617] 安全配置,由词汇表术语 basic 标识(即 "scheme": "basic"),使用未加密的用户名和 密码。

18 BasicSecurityScheme 层级中的词汇表术语
词汇表术语 描述 赋值 类型
name 查询、header、cookie 或 uri 参数的名称。 可选 string
in 指定安全认证信息的位置。 有默认值 string(以下之一: headerquerybodycookieauto
5.3.3.6 DigestSecurityScheme

Digest Access Authentication [RFC7616] 安全配置,由词汇表术语 digest 标识(即 "scheme": "digest")。该方案类似于 basic authentication,但增加了避免 中间人攻击的特性。

19 DigestSecurityScheme 层级中的词汇表术语
词汇表术语 描述 赋值 类型
name 查询、header、cookie 或 uri 参数的名称。 可选 string
in 指定安全认证信息的位置。 有默认值 string(以下之一: headerquerybodycookieauto
qop 保护质量。 有默认值 string(以下之一: authauth-int
5.3.3.7 APIKeySecurityScheme

API key 认证安全配置, 由词汇表术语 apikey 标识(即 "scheme": "apikey")。当访问令牌是不透明的时应使用该方案, 例如云服务提供商提供了某种未知或专有格式的 密钥。在这种情况下,该密钥可能并未使用 标准令牌格式。该方案表示服务提供商提供的密钥 需要使用 "in" 字段所指示的机制, 作为服务请求的一部分提供。

20 APIKeySecurityScheme 层级中的词汇表术语
词汇表术语 描述 赋值 类型
name 查询、header、cookie 或 uri 参数的名称。 可选 string
in 指定安全认证信息的位置。 有默认值 string(以下之一: headerquerybodycookieuriauto
5.3.3.8 BearerSecurityScheme

Bearer Token [RFC6750] 安全配置,由词汇表术语 bearer 标识(即 "scheme": "bearer"),用于 bearer token 独立于 OAuth2 使用的情况。如果指定了 oauth2 方案,通常没有必要 同时指定该方案,因为它已被隐含。对于 format,值 jwt 表示 符合 [RFC7519], jws 表示符合 [RFC7797], cwt 表示符合 [RFC8392],而 jwe 表示符合 [RFC7516];alg 的值 按与这些标准一致的方式解释。 其他 bearer token 的格式和 算法 MAY 在词汇表扩展中指定

21 BearerSecurityScheme 层级中的词汇表术语
词汇表术语 描述 赋值 类型
authorization 授权服务器的 URI。 可选 anyURI
name 查询、header、cookie 或 uri 参数的名称。 可选 string
in 指定安全认证信息的位置。 有默认值 string(以下之一: headerquerybodycookieauto
alg 编码、加密或摘要算法。 有默认值 string(例如 ES256ES512-256
format 指定安全认证信息的格式。 有默认值 string(例如 jwtcwtjwejws
5.3.3.9 PSKSecurityScheme

预共享密钥认证安全配置, 由词汇表术语 psk 标识(即 "scheme": "psk")。 这用于表明使用了预共享密钥标准, 例如 TLS-PSK [RFC4279], 并且用于密钥的密码套件将在协议协商期间 建立。

22 PSKSecurityScheme 层级中的词汇表术语
词汇表术语 描述 赋值 类型
identity 提供可用于选择或确认的信息的 标识符。 可选 string
5.3.3.10 OAuth2SecurityScheme

用于符合 [RFC6749] 和 [RFC8252] 的系统的 OAuth 2.0 认证安全配置, 由词汇表术语 oauth2 标识(即 "scheme": "oauth2")。

23 OAuth2SecurityScheme 层级中的词汇表术语
词汇表术语 描述 赋值 类型
authorization 授权服务器的 URI。 可选 anyURI
token 令牌服务器的 URI。 可选 anyURI
refresh 刷新服务器的 URI。 可选 anyURI
scopes 以数组形式提供的一组授权范围标识符。 这些标识符在授权服务器返回的令牌中提供, 并与 forms 相关联,以标识客户端 可以访问哪些资源以及如何访问。与 form 关联的值 SHOULD 从 该 form 上激活的 OAuth2SecurityScheme 中定义的值中选择。 可选 string 或由 数组 组成的 string
flow 授权流。 强制 string(例如 codeclient

对于 code 流,authorizationtoken 词汇表术语MUST 被包含。 对于 client 流,token 词汇表术语 MUST 被包含。 对于 client 流,authorization 词汇表术语 MUST NOT 被包含。 每个 流的强制元素汇总在下表中:

元素 code client
authorization 强制 省略
token 强制 强制
refresh 可选 可选

5.3.4 超媒体控件 词汇定义

当前模型为由暴露的(带类型的) Web 链接和 Web forms 提供表示。Link 类定义反映了 Web Linking [RFC8288] 中定义术语的 一个非常常见的子集。定义的术语可用于 例如描述与另一个的关系,例如一个 Lamp Thing 由一个 Switch Thing 控制。 Form 类对应一种新引入的 超媒体控件形式,用于操纵 (以及其他 Web 资源)的状态。

5.3.4.2 Form

form 可被视为如下陈述:“要在 form 上下文上执行一个 操作类型操作,请向 提交目标发出一个 请求方法 请求”,其中可选的 form 字段 可以进一步描述所需的请求。在物描述中, form 上下文是周围的对象, 例如属性、动作和事件,或物自身(用于元交互)。

26 Form 层级中的词汇表术语
词汇表术语 描述 赋值 类型
href 链接的目标 IRI 或 form 的提交目标。 强制 anyURI
contentType 基于媒体类型 (例如 text/plain)以及该媒体类型的潜在 参数(例如 charset=utf-8)分配内容类型 [RFC2046]。 可选 string
contentCoding 内容编码值表示已经或可以应用于 表示的编码转换。内容编码主要用于 允许表示被压缩或以其他有用方式转换, 同时不丢失其底层媒体类型的身份,也不 丢失信息。内容编码的示例包括 "gzip"、"deflate" 等。 可选 string
security 一组安全定义名称,从 securityDefinitions 中定义的名称中选取。 要访问资源,必须全部满足这些定义。 可选 string 或由 数组 组成的 string
scopes 以数组形式提供的一组授权范围标识符。 这些标识符在授权服务器返回的令牌中提供, 并与 forms 关联,以标识客户端 可以访问哪些资源以及如何访问。与 form 关联的值 SHOULD 从 该 form 上激活的 OAuth2SecurityScheme 中定义的值中选择。 可选 string 或由 数组 组成的 string
response 如果例如输出通信元数据与输入 元数据不同(例如输出 contentType 不同于 输入 contentType),可以使用这个可选术语。 response 名称包含仅对主响应消息有效的 元数据。 可选 ExpectedResponse
additionalResponses 如果可能存在附加的预期响应, 例如用于错误报告,可以使用该可选术语。 每个附加响应都需要以某种方式 与其他响应区分开来(例如指定协议特定的错误代码), 并且也可以拥有自己的数据模式。 可选 数组,其元素为 AdditionalExpectedResponse
subprotocol 指示在给定协议有多个选项时, 交互将通过哪种确切机制完成。 例如,对于 HTTP 和事件,它指示应使用 若干可用机制中的哪一种来进行异步通知, 如长轮询 (longpoll)、WebSub [websub] (websub)、Server-Sent Events (sse) [html](也称为 EventSource)。请注意,对子协议选择没有 限制,其他机制也可以由该 subprotocol 术语声明。 可选 string(例如 longpollwebsubsse
op 指示执行该 form 所描述操作的语义意图。 例如,属性交互允许 get 和 set 操作。协议绑定可能包含一个用于 get 操作的 form,以及另一个用于 set 操作的 form。op 属性指示哪个 form 对应哪个操作,并允许客户端为所需操作选择 正确的 form。op 可以被赋予一个或多个交互动词, 每个动词表示某个操作的语义意图。 有默认值 string 或由 数组 组成的 string(以下之一: readpropertywritepropertyobservepropertyunobservepropertyinvokeactionqueryactioncancelactionsubscribeeventunsubscribeeventreadallpropertieswriteallpropertiesreadmultiplepropertieswritemultiplepropertiesobserveallpropertiesunobserveallpropertiessubscribealleventsunsubscribealleventsqueryallactions

contentCoding 属性的可能值可以在例如 IANA HTTP 内容编码注册表中找到。

form 的可能操作类型列表是固定的。 截至本规范版本,该列表仅包含实现 [wot-architecture11] 中描述的 WoT 交互模型所必需的已知类型。 标准的未来版本可以扩展该列表,但 操作类型 MUST 限制为下表中的值。

27 已知操作 类型
操作类型 描述
readproperty 标识属性 可供性上的读取操作,用于检索相应 数据。
writeproperty 标识属性 可供性上的写入操作,用于更新相应 数据。
observeproperty 标识属性 可供性上的观察操作,用于在属性更新时收到新数据 通知。
unobserveproperty 标识属性可供性上的取消观察操作, 用于停止相应 通知。
invokeaction 标识动作 可供性上的调用操作,用于执行相应 动作。
queryaction 标识动作 可供性上的查询操作,用于获取 相应动作的状态。
cancelaction 标识动作 可供性上的取消操作,用于取消正在进行的相应 动作。
subscribeevent 标识事件 可供性上的订阅操作,用于在事件发生时由物发送 通知。
unsubscribeevent 标识事件 可供性上的取消订阅操作,用于停止相应 通知。
readallproperties 标识物上的 readallproperties 操作, 用于在单个交互中检索所有属性的 数据。
writeallproperties 标识物上的 writeallproperties 操作, 用于在单个交互中更新所有可写 属性的数据。
readmultipleproperties 标识物上的 readmultipleproperties 操作,用于在单个交互中检索 所选属性的数据。
writemultipleproperties 标识物上的 writemultipleproperties 操作,用于在单个交互中更新 所选可写属性的数据。
observeallproperties 标识属性上的 observeallproperties 操作, 用于在任一属性更新时收到新数据 通知。
unobserveallproperties 标识属性上的 unobserveallproperties 操作,用于在单个交互中停止来自所有属性的 通知。
queryallactions 标识物上的 queryallactions 操作, 用于在单个交互中获取所有动作的 状态。
subscribeallevents 标识事件上的 subscribeallevents 操作, 用于在单个交互中订阅来自所有 事件的通知。
unsubscribeallevents 标识事件上的 unsubscribeallevents 操作, 用于在单个交互中取消订阅来自所有 事件的通知。

WoT 生产者物描述 可能具有多个 forms 条目,例如具有不同协议和/或 内容类型声明,而消费者可能支持其中一些。 在这种情况下,消费者可以选择任何对其可用的 form 条目(例如协议和内容类型受支持)。一旦选择一个 form,就预期消费者会尽可能持续 将其用于与 WoT 生产者的每次新交互。

5.3.4.2.1 将 op 值 映射到数据模式

本节为非规范性内容。

可与 TD 一起使用的协议遵循 请求-响应或事件机制。可供性的数据 模式通常与 forms 中使用的 op 关键字相关。 下表以资料性方式总结了可用的 与数据模式相关的术语及其与 op 关键字的关系。

  • Consumer to Thing 适用于消费者发送给 物的消息,例如写入属性的值。
  • Thing to Consumer 适用于物发送给 消费者的消息,例如读取属性结果中的 属性值。
  • 如果数据模式与操作之间没有相关性, 则意味着执行该操作不需要负载,或不 预期操作结果有负载。
28 将 op 值映射到 数据 模式
操作类型 Consumer to Thing DataSchema 相关性 Thing to Consumer DataSchema 相关性
readproperty 无相关性。 Property Affordance 中所有不带 "writeOnly":true 的字段。
writeproperty Property Affordance 中所有不带 "readOnly":true 的字段。 无相关性。 additionalResponses 可在 form 层级使用。
observeproperty 无相关性。 Property Affordance 中所有不带 "writeOnly":true 的字段。
unobserveproperty 无相关性。 无相关性。
invokeaction input 键的值。 output 键的值。
queryaction 无相关性。 无相关性。 additionalResponses 可在 form 层级使用。
cancelaction 无相关性。 无相关性。 additionalResponses 可在 form 层级使用。
subscribeevent subscription 键的值, 包含所有不带 "readOnly":true 的字段 subscription 键的值, 包含所有不带 "writeOnly":true 的字段
unsubscribeevent subscription 键的值, 包含所有不带 "readOnly":true 的字段 subscription 键的值, 包含所有不带 "writeOnly":true 的字段
: writeproperty 与 observeproperty 的关系

写入属性并不 一定意味着新值会被发送给正在观察该属性的 消费者。这取决于 协议和实现。

: 进一步的数据模式映射

关于如何将操作映射到数据模式的进一步规范, 以及如何映射诸如 readallproperties 这样的元 操作,可在 [WOT-BINDING-TEMPLATES] 的相应协议规范中找到。

可选的 response 名称-值对 可用于为预期的 响应消息提供元数据。在核心词汇中,它只能 包含内容类型信息,但也可以应用 TD 上下文 扩展。如果未提供 response 名称-值对,则 MUST 假定 响应的内容类型等于赋给 Form 实例的 内容类型。注意, ExpectedResponse 中的 contentType 没有 默认值

在某些情况下可能存在附加响应。 一个例子是错误响应,但在某些情况下也可能 存在附加的成功响应。在这种情况下, response 名称-值对仍用于主响应, 但也可以提供 additionalResponses, 其值为 AdditionalExpectedResponse 对象数组。 每个附加响应必须以某种方式与主响应区分开来, 可以通过 contentType, 或者通过协议特定设置(如错误代码 header 值)。 每个附加响应也可以具有一个数据模式, 该模式可不同于该交互的普通输出数据模式。

在某些用例中,输入和输出数据可能以 不同形式表示,例如某个动作 接受 JSON,但返回图像。在这种 情况下,可选的 response 键-值对 可以描述预期响应的内容类型。 由于没有定义默认值,以下 断言适用:

  • 如果 form 内的 response 对象中没有定义 contentType 值, 消费者 MUST 预期 相应响应不包含任何 负载。
  • 如果 form 内的 response 对象中定义了内容类型, 消费者 MUST 预期响应包含 相应格式的负载,例如在 image/jpeg 的情况下为图像。

类似考量也适用于附加 响应:

  • 如果 附加预期响应的内容类型 不同于 form 的内容类型, Form 实例 MUST 在与名称 additionalResponses 关联的数组中包含一个条目。
  • 如果 附加预期响应对象中没有定义 contentType 值,消费者 MUST 预期相应响应不包含任何 负载。
  • 如果 附加预期响应的数据模式不同于 交互的输出数据模式,则 Form MUST 在与名称 additionalResponses 关联的数组中 包含一个条目,该条目包含名称 schema 的值。
  • 当不存在 contentType 时, 附加预期响应对象的 schema MUST NOT 被定义。

上文解释了请求和响应变化的不同情况。 C. 物 描述中的 contentType 用法中的表以简洁 方式总结了这些情况。

5.3.4.3 ExpectedResponse

描述主响应的预期 响应消息的通信元数据。

29 ExpectedResponse 层级中的词汇表术语
词汇表术语 描述 赋值 类型
contentType 基于媒体类型 (例如 text/plain)以及该媒体类型的潜在 参数(例如 charset=utf-8)分配内容类型 [RFC2046]。 可选 string
5.3.4.4 AdditionalExpectedResponse

描述附加响应的预期 响应消息的通信元数据。

30 AdditionalExpectedResponse 层级中的词汇表术语
词汇表术语 描述 赋值 类型
success 标示附加响应是否不应被 视为错误。 有默认值 boolean
schema 如果附加响应的输出数据模式不同于默认 输出数据模式,则用于定义该附加响应的 输出数据模式。必须使用 schemaDefinitions 映射中给出的 先前定义的名称,而不是 DataSchema 对象。 可选 string
contentType 基于媒体类型 (例如 text/plain)以及该媒体类型的潜在 参数(例如 charset=utf-8)分配内容类型 [RFC2046]。 可选 string

5.4 默认值定义

当 TD 中的赋值 缺失时,TD 处理器MUST 遵循 默认 值赋值,这些赋值在默认值 定义表中表达。

下表给出了 TD 信息模型中定义的所有默认值

31 当 TD 中不存在术语时 使用的词汇表 术语默认值
词汇表术语 默认值 注释
PropertyAffordance readOnly false 此词汇表术语的默认值仅适用于 PropertyAffordance 层级 定义。在其他上下文中,例如 DataSchema 定义,该词汇表 术语是可选的。
PropertyAffordance writeOnly false 此词汇表术语的默认值仅适用于 PropertyAffordance 层级 定义。在其他上下文中,例如 DataSchema 定义,该词汇表 术语是可选的。
PropertyAffordance observable false
ActionAffordance safe false
ActionAffordance idempotent false
AdditionalExpectedResponse success false
Form contentType application/json
Form op 数组,其元素为 readOnlywriteOnly 设置为 false 时包含元素 readpropertywritepropertystring,或当 readOnly 设置为 true 时包含元素 readproperty数组 string,或当 writeOnly 设置为 true 时包含元素 writeproperty数组 string
如果定义在 PropertyAffordance 的实例中
Form op invokeaction 如果定义在 ActionAffordance 的实例中
Form op 数组,其元素为 subscribeeventunsubscribeeventstring 如果定义在 EventAffordance 的实例中
BasicSecurityScheme in header
DigestSecurityScheme in header
DigestSecurityScheme qop auth
APIKeySecurityScheme in query
BearerSecurityScheme in header
BearerSecurityScheme alg ES256
BearerSecurityScheme format jwt

此外,以下考量适用于默认值的使用:

注意,默认值和扩展机制可以按顺序 应用。例如,缺少 "readOnly""writeOnly" 意味着 默认值 false 会应用于二者, 如31所示,这进而意味着 "op" 的默认值是 ["readproperty", "writeproperty"]。使用协议绑定的 默认方法时,这意味着 "GET""PUT" 分别对应于 "readproperty""writeproperty"。 但是,遵循多个操作的扩展 机制,会在内部创建两个单独的 forms, 每个操作一个,并指示默认 方法。然后,应用默认上下文扩展 机制,将 htv 前缀的定义添加到 @context。下面的 示例显示初始 TD,以及在应用所有默认值和扩展 机制后的完全扩展 TD。

6. TD 表示格式

WoT 物描述表示物,并基于 5. TD 信息模型来建模和 构造。 本节为定义一种基于 JSON 的表示格式, 即对 TD 信息模型所定义的 Thing 的实例进行序列化。

TD 处理器MUST 能够按照 6.1 到 JSON 类型的映射6.3 信息模型 序列化中指出的规则,将物 描述序列化为 JSON 格式 [RFC8259] 和/或从 该格式反序列化物描述

TD 信息模型的 JSON 序列化与 JSON-LD 1.1 [json-ld11] 的语法保持一致,以简化 语义求值。因此,TD 表示格式既可以作为 原始 JSON 处理,也可以使用 JSON-LD 1.1 处理器 处理(有关语义处理的详情,请参阅 D. JSON-LD 上下文用法以及 命名空间 IRI 下的文档,例如 https://www.w3.org/2019/wot/td)。

为了支持可互操作的国际化, TD MUST 按照 RFC8259 [RFC8259] 第 8.1 节中为开放生态系统定义的要求进行序列化。 总结而言,这要求如下:

6.1 到 JSON 类型的映射

TD 信息模型经过构造,使模型对象与 JSON 类型之间存在 简单映射。每个 实例都映射到一个 JSON 对象,其中实例的每个名称-值对都是该 JSON 对象的一个成员。

5.3 类定义中提及的每个简单 类型 (即 stringanyURIdateTimeintegerunsignedIntdoubleboolean)都按照下列规则映射到一个原始 JSON 类型 (string、number、boolean)。这些规则 适用于名称-值对中的值:

TD 信息模型的每个复杂类型(即 数组映射 实例)都按照下列规则映射到 结构化 JSON 类型(array 和 object):

6.2 省略默认值

物描述序列化可以省略已定义 默认值词汇表术语, 这些默认值列于 5.4 默认值定义给出的表中。

以下示例展示了来自示例 1的 TD 实例, 并带有一个复选框,用于同时包含带有默认值的成员 (= 复选框选中)。这些成员可以被省略(= 复选框 未选中),以简化 TD 序列化。注意, TD 处理器解释这些被省略的成员时,与 它们以给定默认值显式存在时相同。

请注意,根据所使用的协议 绑定,可能适用附加的协议特定词汇表术语。 它们也可能具有关联的默认值, 因此也可以按本小节所述被省略。 更多信息可在8.1.1 协议绑定中找到。

6.3 信息模型 序列化

6.3.1 物根对象

物描述是一种数据结构,其根为 对象 类型 Thing。相应地,物描述的 JSON 序列化是一个 JSON 对象, 它是由 TD 信息模型构造的语法树的根。

TD 序列化的根 元素 MUST 是一个 JSON 对象, 该对象包含一个名称为 @context 的成员,且其 值为字符串类型,或为等于或相应包含 https://www.w3.org/ns/wot-next/td 的数组类型。

通常,该 URI 用于标识本规范所定义的 TD 表示格式版本。对于 JSON-LD 处理 [json-ld11],该 URI 指定物描述上下文文件。类型为数组的 @context 表示 TD 上下文扩展 (详情见 7. TD 上下文 扩展)。

{
    "@context": "https://www.w3.org/ns/wot-next/td",
    // ...
}

Thing 实例中 名称属于 Thing签名词汇表术语的所有名称-值对, MUST 被 序列化为根对象的 JSON 成员。

下面给出一个序列化根对象的 TD 片段,其中包含所有 强制和可选成员:

示例 8:物 序列化样例
{
    "@context": "https://www.w3.org/ns/wot-next/td",
    "@type": "Thing",
    "id": "urn:uuid:1b37933b-3212-4dad-9c2c-74c6042c3e2b",
    "title": "MyThing",
    "titles": {/*...*/},
    "description": "Human readable information.",
    "descriptions": {/*...*/},
    "support": "mailto:support@example.com",
    "version": {/*...*/},
    "created": "2018-11-14T19:10:23.824Z",
    "modified": "2019-06-01T09:12:43.124Z",
    "securityDefinitions": {/*...*/},
    "security": /*...*/,
    "base": "https://servient.example.com/",
    "properties": {/*...*/},
    "actions": {/*...*/},
    "events": {/*...*/},
    "links": [...],
    "forms": [...]
}

Thing 实例中赋给 versionsecurityDefinitionsdescriptionsschemaDefinitionsuriVariablespropertiesactionsevents 的所有 值 MUST 被 序列化为 JSON 对象。

Thing 实例中赋给 linksforms 的所有值 MUST 被序列化为 JSON 数组, 其中包含分别按 6.3.8 links6.3.9 forms中定义的 JSON 对象。

Thing 实例中赋给 security 的值 MUST 被序列化为 JSON 字符串,或被序列化为其元素为 JSON 字符串的 JSON 数组。

6.3.2 人类可读元数据

TD 文档中使用名为 titledescription 的 JSON 成员来 提供人类可读元数据。它们可用作 检查 TD 文档的开发者注释,或用作 用户界面的显示文本。

5.3.1.1 Thing 中所定义,用于 显示人类可读元数据的基本文本方向,可以通过 首强规则等启发式方法估计,或从语言信息中 推断。在 TD 文档中,默认语言由 @context 中赋给 @language 的值定义, 并且该值连同必要时的文字系统子标签,可用于 确定基本文本方向。但是, 在解释人类可读文本时,每个人类可读 字符串值 MUST 被独立 处理。换言之,TD 处理器 不能将一个字符串中的方向变化延续到另一个字符串, 也不能根据 TD 中其他位置的另一个字符串推断 某个字符串的方向。

下面显示了一个使用 titledescription 的 TD 片段。默认 语言通过 @context 数组中某个 JSON 对象内 @language 成员的定义 设置为 en

{
    "@context": [
        "https://www.w3.org/ns/wot-next/td",
        { "@language": "en" }
    ],
    "title": "MyThing",
    "description": "Human readable information.",
    // ...
    "properties": {
        "on": {
            "title": "On/Off",
            "type": "boolean",
            "forms": [...]
        },
        "status": {
            "title": "Status",
            "type": "object",
            // ...
            "forms": [...]
        }
    },
    // ...
}

Strings on the Web [STRING-META] 建议使用元数据来确定字符串值的基本 方向鉴于 物描述格式基于 JSON-LD 1.1 [json-ld11], @direction 及其字符串值 "ltr""rtl" 和 null 值 null MAY@context 内使用,用于指示整个 TD 文档中人类可读字符串的默认文本方向。 @direction 等元数据不存在时,TD 消费者 SHOULD 使用 首强检测作为回退。 对于 MultiLanguage 映射,TD 消费者 MAY 根据各个 字符串的语言标签推断基本 方向这些可概括为以下步骤, TD 消费者可以根据 TD 中提供的信息实现这些步骤。

  1. 文件级元数据:使用 @context 中找到的 @direction 值。
  2. 根据语言猜测:使用 @language 的值,然后猜测文本 方向。
  3. 首强:使用字符串中第一个 强方向性字符。这等价于在 HTML 属性中使用 dir=auto

请注意,在本规范当前版本中, 字符串特定方向元数据尚不可用。工作组正在制定一种 机制来使其成为可能。在此之后,它将成为 TD 消费者处理文本方向的首选方式。

此外,下面的示例说明了 @direction@language 术语的使用。更多详细信息见 [json-ld11] 和 [string-meta]。

{
     "@context": [
         "https://www.w3.org/ns/wot-next/td",
         {
           "@language": "ar-EG",
           "@direction": "rtl"
         }
     ],
     "title": "شيء يخصني يقيس درجة الحرارة",
     "description": "شيء يقيس درجة الحرارة و يظهر حالته",
     // ...
     "properties": {
         "temp": {
             "title": "درجة الحرارة",
             "type": "boolean",
             "forms": [...]
         },
         "status": {
             "title": "حالة",
             "type": "object",
             // ...
             "forms": [...]
         }
     },
     // ...
 }

TD 文档中使用名为 titlesdescriptions 的 JSON 成员, 以在单个 TD 文档内提供多种语言的人类可读元数据。 MultiLanguage 映射的所有名称-值 对 MUST 被序列化为 JSON 对象的成员,其中名称是由 [BCP47] 定义的有效语言标签(另见 W3C I18N Glossary),值是以该标签 指示语言书写的人类可读字符串。详情见 5.3.1.7 MultiLanguageTD 文档中的所有 MultiLanguage 对象 SHOULD 包含相同的一组 语言成员。

下面给出一个在不同层级使用 titlesdescriptions 的 TD 片段:

{
    "@context": "https://www.w3.org/ns/wot-next/td",
    "title": "MyThing",
    "titles": {
        "en": "MyThing",
        "de": "MeinDing",
        "ja": "私の物",
        "zh-Hans": "我的东西",
        "zh-Hant": "我的東西"
    },
    "descriptions": {
        "en": "Human readable information.",
        "de": "Menschenlesbare Informationen.",
        "ja": "人間が読むことができる情報",
        "zh-Hans": "人们可阅读的信息",
        "zh-Hant": "人們可閱讀的資訊"
    },
    // ...
    "properties": {
        "on": {
            "titles": {
                "en": "On/Off",
                "de": "An/Aus",
                "ja": "オンオフ",
                "zh-Hans": "开关",
                "zh-Hant": "開關" },
            "type": "boolean",
            "forms": [...]
        },
        "status": {
            "titles": {
                "en": "Status",
                "de": "Zustand",
                "ja": "状態",
                "zh-Hans": "状态",
                "zh-Hant": "狀態" },
            "type": "object",
            // ...
            "forms": [...]
        }
    },
    // ...
}

TD 实例也可以将 titledescriptiontitlesdescriptions 结合使用。 titletitles,或 descriptiondescriptions 出现在同一 JSON 对象中时,titledescription 的值 MAY 被 视为默认文本。 titletitles,或 descriptiondescriptions 出现在 TD 文档中时,每个 titledescription 成员 SHOULD 分别具有对应的 titlesdescriptions 成员。 默认文本的语言由默认语言指示,通常由 物描述实例的创建者设置。

{
    "@context": [
        "https://www.w3.org/ns/wot-next/td",
        { "@language": "de" }
    ],
    "title": "MeinDing",
    "titles": {
        "en": "MyThing",
        "de": "MeinDing",
        "ja": "私の物",
        "zh-Hans": "我的东西",
        "zh-Hant": "我的東西"
    },
    "description": "Menschenlesbare Informationen.",
    "descriptions": {
        "en": "Human readable information.",
        "de": "Menschenlesbare Informationen.",
        "ja": "人間が読むことができる情報",
        "zh-Hans": "人们可阅读的信息",
        "zh-Hant": "人們可閱讀的資訊"
    },
    // ...
    "properties": {
        "on": {
            "title": "An/Aus",
            "titles": {
                "en": "On/Off",
                "de": "An/Aus",
                "ja": "オンオフ",
                "zh-Hans": "开关",
                "zh-Hant": "開關" },
            "type": "boolean",
            "forms": [...]
        },
        "status": {
            "title": "Zustand",
            "titles": {
                "en": "Status",
                "de": "Zustand",
                "ja": "状態",
                "zh-Hans": "状态",
                "zh-Hant": "狀態" },
            "type": "object",
            // ...
            "forms": [...]
        }
    },
    // ...
}

设置默认语言的另一种可能方式是 通过语言协商机制,例如 HTTP 的 Accept-Language header 字段。 在 默认语言已经协商确定的情况下, @language 成员 MUST 存在,以指示协商结果以及所返回 内容的相应默认语言。 当 默认语言已经成功协商时,TD 文档 SHOULD 优先在 titledescription 成员中包含 适当匹配的值,而不是在 titlesdescriptions 成员中使用 MultiLanguage 对象。 不过请注意,物 MAY 选择不支持此类动态生成的 TD, 也可以选择不支持语言协商(例如由于资源 限制)。

不能保证 TD 中的字符串会在 HTML 渲染上下文中 显示。事实上,为了缓解 11.5 脚本 注入中描述的 XSS 安全风险,从 TD 获取的字符串中嵌入的 HTML 标签,在将这些字符串嵌入 网页或 Web 应用的应用程序中应当被清理 (因此不会被解释为 HTML)。因此,字符串中嵌入的 HTML 不是指定文本渲染 方向的适当机制。

6.3.3 version

VersionInfo 实例中的所有名称-值对,其中名称是包含在 VersionInfo签名中的词汇表术语MUST 以该 词汇表术语作为名称, 序列化为 JSON 成员。

下面给出一个版本信息对象的 TD 片段:

{
    // ...
    "version": { "instance": "1.2.1" },
    // ...
}

version 成员意在作为一个容器, 用于基于 TD 上下文扩展提供附加的 应用和/或设备特定版本 信息。详情见 7.1 语义 标注

6.3.4 securityDefinitionssecurity

Thing 实例中,赋给 securityDefinitions 的值是 SecurityScheme 实例的映射 SecurityScheme 实例映射的 所有名称-值对 MUST 序列化为由该映射序列化得到的 JSON 对象的成员;一个对的名称 MUST 序列化为 JSON 字符串,并且 该对的值,即 SecurityScheme 的实例,MUST 序列化为 JSON 对象。

SecurityScheme 的某个 子类实例中的所有名称-值对, 其中名称是包含在该子类签名中,或包含在 SecurityScheme签名中的词汇表术语MUST 以该词汇表术语作为 名称,序列化为由该 SecurityScheme 子类实例序列化得到的 JSON 对象的成员。

下面的 TD 片段展示了一个简单安全 配置,它指定在 header 中使用 basic 用户名/密码 认证。为 in 给出的值实际上是默认值header),因此可以省略。在 securityDefinitions 映射中给出了一个具名 安全配置(basic_sc)。在此示例中, 该定义通过在 security 成员中包含其 JSON 名称来激活。

{
    // ...
    "securityDefinitions": {
        "basic_sc": {
            "scheme": "basic",
            "in": "header"
        }
    },
    "security": "basic_sc",
    // ...
}

TD 中的安全配置是强制的。 至少一个安全定义 MUST 通过 物层级 (即 TD 根对象)中的 security 成员激活。 这种配置可被视为与交互所需的默认安全机制。 安全定义 MAY 也可以通过在 form 对象中包含 security 成员,在 form 元素层级激活;这会覆盖(即完全 替换)在物 层级激活的所有定义。

在不需要任何安全机制的情况下,提供了 nosec 安全方案。的最小安全 配置,是在物层级激活 nosec 安全方案,如下例所示:

{
    "@context": "https://www.w3.org/ns/wot-next/td",
    "id": "urn:uuid:e9ecb6ad-cd4c-481b-96ce-5b4c57ddb844",
    "title": "MyThing",
    "description": "Human readable information.",
    "support": "https://servient.example.com/contact",
    "securityDefinitions": { "nosec_sc": { "scheme": "nosec" }},
    "security": "nosec_sc",
    "properties": {/*...*/},
    "actions": {/*...*/},
    "events": {/*...*/},
    "links": [/*...*/]
}
6.3.4.1 多个安全 定义

为了给出一个更复杂的示例,假设我们有一个 ,其中除一个之外的所有 交互 可供性都需要 basic 认证,而该例外项不需要认证。 对于 status 属性和 toggle 动作,要求 basic 认证,并在 物层级定义。对于 overheating 事件,则不需要 认证,因此安全配置在 form 层级被覆盖。

{
    // ...
    "securityDefinitions": {
        "basic_sc": {"scheme": "basic"},
        "nosec_sc": {"scheme": "nosec"}
    },
    "security": "basic_sc",
    // ...
    "properties": {
        "status": {
            // ...
            "forms": [{
                "href": "https://mylamp.example.com/status"
            }]
        }
    },
    "actions": {
        "toggle": {
            // ...
            "forms": [{
                "href": "https://mylamp.example.com/toggle"
            }]
        }
    },
    "events": {
        "overheating": {
            // ...
            "forms": [{
                "href": "https://mylamp.example.com/oh",
                "security": "nosec_sc"
            }]
        }
    }
}

TD 也可以指定安全方案的组合。 下面是一个 TD 片段,展示了在代理上使用 digest 认证, 同时在上结合 bearer token 认证。 在 digest 方案中,in默认值 (即 header)被省略,但仍然适用。 注意,相应的私有安全配置,例如用户名/密码 和 token,需要在消费者中配置, 以便成功交互。当激活多个安全 定义时,security 成员会变成一个 数组。

{
    // ...
    "securityDefinitions": {
        "proxy_sc": {
            "scheme": "digest",
            "proxy": "https://portal.example.com/"
        },
        "bearer_sc": {
            "scheme": "bearer",
            "in": "header",
            "format": "jwt",
            "alg": "ES256",
            "authorization": "https://servient.example.com:8443/"
        }
    },
    "security": ["proxy_sc", "bearer_sc"],
    // ...
}

然而,现在不推荐 在 security 元素中使用包含多个元素的 数组来组合安全方案; 应改为使用 ComboSecurityScheme SHOULD以下示例与上面的示例 完全等价,并演示了这一点:

{
    // ...
    "securityDefinitions": {
        "proxy_sc": {
            "scheme": "digest",
            "proxy": "https://portal.example.com/"
        },
        "bearer_sc": {
            "scheme": "bearer",
            "in": "header",
            "format": "jwt",
            "alg": "ES256",
            "authorization": "https://servient.example.com:8443/"
        },
        "combo_sc": {
            "scheme": "combo",
            "allOf": ["proxy_sc", "bearer_sc"]
        }
    },
    "security": "combo_sc",
    // ...
}
6.3.4.2 Forms 中的 security

也可以为同一个交互 可供性内的不同 forms 指定安全配置。 对于支持多个协议的设备,例如 HTTP 和 CoAP [RFC7252], 这些协议支持不同安全机制时,这可能是必需的。 当允许替代认证机制时,这也很有用。下面的 TD 片段演示了激活一个属性可供性的三种 可能方式:通过带 basic 认证的 HTTPS、通过 digest 认证、以及通过 bearer token 认证。 换言之,在多个 forms 中使用不同安全配置, 提供了一种以“OR”方式组合安全 机制的方法。相反,将多个安全配置放入同一个 security 成员中会以“AND”方式组合它们, 因为在这种情况下必须全部满足这些配置,才能允许激活该 交互 可供性。注意,在物层级激活一个 (默认)配置仍然是强制的。

{
    // ...
    "securityDefinitions": {
        "basic_sc": { "scheme": "basic" },
        "digest_sc": { "scheme": "digest" },
        "bearer_sc": { "scheme": "bearer" }
    },
    "security": "basic_sc",
    // ...
    "properties": {
        "status": {
            // ...
            "forms": [{
                "href": "https://mylamp.example.com/status"
            }, {
                "href": "https://mylamp.example.com/status",
                "security": "digest_sc"
            }, {
                "href": "https://mylamp.example.com/status",
                "security": "bearer_sc"
            }]
        }
    },
    // ...
}
6.3.4.3 ComboSecurityScheme

为了在这种情况下避免冗余,例如重复 form 元素的细节,可以改用带有 oneOfComboSecurityScheme

{
    // ...
    "securityDefinitions": {
        "basic_sc": { "scheme": "basic" },
        "digest_sc": { "scheme": "digest" },
        "bearer_sc": { "scheme": "bearer" },
        "combo_sc": {
            "scheme": "combo",
            "oneOf": [ "basic_sc", "digest_sc", "bearer_sc" ]
        }
    },
    "security": "combo_sc",
    // ...
    "properties": {
        "status": {
            // ...
            "forms": [{
                "href": "https://mylamp.example.com/status"
            }]
        }
    },
    // ...
}
6.3.4.4 OAuth 2.0 用法

作为另一个更复杂的示例,OAuth 2.0 会使用 scopes。这些标识符可能出现在 tokens 中,并且必须与资源中的相应标识符匹配, 才允许访问该资源(或在 W3C WoT 的情况下访问交互 可供性)。例如, 在下面示例中,status 属性可以由 消费者使用包含 scope limited 的 bearer tokens 读取,但 configure 动作只能使用包含 special scope 的 token 调用。Scopes 与角色并不相同,但通常与角色相关联; 例如,可能只有拥有管理员角色的人才被授权执行 “special”交互。Tokens 可以拥有多个 scope, 并由专门的 Web 服务签发给用户。在这个 示例中,可以向管理员签发同时带有 limitedspecial scopes 的 tokens,而普通用户可以获得带有 limited scope 的 tokens。

{
    // ...
    "securityDefinitions": {
        "oauth2_sc": {
            "scheme": "oauth2",
            "flow": "client",
            "token": "https://example.com/token",
            "scopes": ["limited", "special"]
        }
    },
    "security": "oauth2_sc",
    // ...
    "properties": {
        "status": {
            // ...
            "forms": [{
                "href": "https://scopes.example.com/status",
                "scopes": ["limited"]
            }]
        }
    },
    "actions": {
        "configure": {
            // ...
            "forms": [{
                "href": "https://scopes.example.com/configure",
                "scopes": ["special"]
            }]
        }
    },
    // ...
}
6.3.4.5 API key 用法

一个物可以要求执行 onboarding 过程, 其结果是消费者需要 API key 才能与该 物交互。该 API key 可以按照 API key 方案的指定, 以不同方式包含在发往该 物的请求中。下面是一个示例,展示如何将其用作 URI 模板,其中 API key 应在消费者发送 HTTPS 请求时由消费者在 URI 中替换。

{
    // ...
    "securityDefinitions": {
        "apikey_key": {
            "scheme": "apikey",
            "in": "uri",
            "name": "adminKey"
        }
    },
    "security": "apikey_key",
    "properties": {
        "status": {
            // ...
            "forms": [{
                "href": "https://example.com/{adminKey}/status",
                // ...
            }]
        }
    },
    // ...
}

为了在上面所示 URI 模板示例的用法之外, 再举一个使用 ComboSecurityScheme 的示例,假设存在一个安全方案,其中云服务 提供商提供的客户端 ID 和“secret”key 都必须 嵌入到 URL 中。从技术上说,只有 key 真正是秘密的,并且必须带外处理,而不是秘密的客户端 ID 可以嵌入到 TD 中。然而,如果客户端 ID 不能轻易轮换,我们可能希望避免将其嵌入到 TD 中,以增强隐私。在这种情况下,我们可以 组合两个 APIKeySecurityScheme 实例, 二者都将 uri 值用于 in 位置说明符,以声明两个 URI 变量。然后这些变量可以(事实上,必须)在安全方案 处于激活状态的 Formhref 中使用。示例如下:

{
    // ...
    "securityDefinitions": {
        "apikey_key": {
            "scheme": "apikey",
            "in": "uri",
            "name": "secKey"
        },
        "apikey_id": {
            "scheme": "apikey",
            "in": "uri",
            "name": "secClientID"
        },
        "apikey_combo": {
            "scheme": "combo",
            "allOf": ["apikey_key","apikey_id"]
        }
    },
    "security": "apikey_combo",
    // ...
    "properties": {
        "status": {
            // ...
            "forms": [{
                "href": "https://example.com/{secClientID}/status/{secKey}",
                // ...
            }]
        }
    },
    // ...
}

虽然此示例中没有显示,但使用 uriVariables 声明附加 URI 模板变量, 并将它们包含在同一个 URI 模板中,是合法的;不过这些名称不能与 安全方案中声明的名称冲突。像上例那样, 为安全方案中声明的 URI 变量使用特定 前缀,可以更容易地避免名称 冲突。

Body 中的 API Key:在某些系统中,安全参数也可能 随负载一起包含。例如,假设一个系统要求每个 负载都是一个 JSON 对象,其中包含一个名为 auth 的成员,其值是一个对象,该对象包含一个名为 key 的成员,其中包含访问 key。可是,根据 交互不同,JSON 对象中的其他元素可能会变化。 这种情况可以通过使用 body 安全信息位置来处理。 注意,对于这个位置,name 参数实际上是一个 JSON 指针,它相对于其所绑定的每个交互的 DataSchema 根进行求值,这使其可以用于 其他方面会发生变化的负载。作为示例,下面是一盏灯, 它有一个用于设置亮度和颜色的属性,以及两个单独的 动作来打开和关闭它。虽然这些动作的 JSON 负载不同,但 /auth/key 元素出现在相同的 相对位置,因此可以使用单个 JSON 指针。 注意:如果安全 key 出现在不同且不一致的位置, 就有必要使用多个安全方案定义。

{
    // ...
    "securityDefinitions": {
        "apikey_body": {
            "scheme": "apikey",
            "in": "body",
            "name": "/auth/key"
        }
    },
    "security": "apikey_body",
    // ...
    "properties": {
        "color": {
            // ...
            "type": "object",
            "properties": {
                "brightness": {
                    "type": "number",
                    // ...
                },
                "rgb": {
                    "type": "array",
                    // ...
                },
                "auth": {
                    "type": "object",
                    "properties": {
                        "key": {
                           "type": "string"
                        }
                    },
                    "required": ["key"]
                }
            },
            "required": ["brightness", "rgb", "auth"],
            "forms": [{
                "href": "https://example.com/color",
                // ...
            }]
        }
    },
    "action": {
        "on": {
            // ...
            "input": {
                "auth": {
                    "type": "object",
                    "properties": {
                        "key": {
                           "type": "string"
                        }
                    },
                    "required": ["key"]
                }
            },
            "required": ["auth"],
            "forms": [{
                "href": "https://example.com/on",
                // ...
            }]
        },
        "off": {
            // ...
            "input": {
                "auth": {
                    "type": "object",
                    "properties": {
                        "key": {
                           "type": "string"
                        }
                    },
                    "required": ["key"]
                }
            },
            "required": ["auth"],
            "forms": [{
                "href": "https://example.com/off",
                // ...
            }]
        }
    },
    // ...
}
然而,向每个数据模式添加 安全信息相当烦人且冗余。可以通过使用这样一个特性来 简化该示例:如果 body 位置中的 JSON 指针所引用的位置不存在,它会被自动插入。 在这种情况下,上面的示例可以简化为下面这样。 注意,事实上会为 动作 onoff 有效地 创建 一个数据模式,仅用于容纳 安全信息。
{
    // ...
    "securityDefinitions": {
        "apikey_body": {
            "scheme": "apikey",
            "in": "body",
            "name": "/auth/key"
        }
    },
    "security": "apikey_body",
    // ...
    "properties": {
        "color": {
            // ...
            "type": "object",
            "properties": {
                "brightness": {
                    "type": "number",
                    // ...
                },
                "rgb": {
                    "type": "array",
                    // ...
                }
            },
            "required": ["brightness", "rgb"],
            "forms": [{
                "href": "https://example.com/color",
                // ...
            }]
        }
    },
    "action": {
        "on": {
            // ...
            "required": ["auth"],
            "forms": [{
                "href": "https://example.com/on",
                // ...
            }]
        },
        "off": {
            // ...
            "forms": [{
                "href": "https://example.com/off",
                // ...
            }]
        }
    },
    // ...
}

6.3.5 properties

Thing 实例中赋给 properties 的值,是 PropertyAffordance 实例的映射 PropertyAffordance 实例映射的所有名称-值 对 MUST 序列化为由该映射序列化得到的 JSON 对象的成员;一个对的名称 MUST 序列化为 JSON 字符串,并且 该对的值,即 PropertyAffordance 的实例,MUST 序列化为 JSON 对象。

PropertyAffordance 实例中的所有名称-值对,其中名称是 包含在 PropertyAffordanceInteractionAffordanceDataSchema 的(某个) 签名中的 词汇表术语MUST 以该 词汇表术语作为 名称,序列化为由该 PropertyAffordance 实例序列化得到的 JSON 对象的成员。 有关序列化 DataSchema 实例的详情,见 6.3.10 数据 模式

PropertyAffordance 实例中赋给 forms 的值 MUST 序列化为 JSON 数组, 其中包含一个或多个 JSON 对象序列化, 如 6.3.9 forms 中所定义。

下面给出两个属性可供性的 片段:

6.3.6 actions

Thing 实例中,赋给 actions 的值是 ActionAffordance 实例的映射 ActionAffordance 实例映射的所有名称-值对 MUST 序列化为由该映射序列化得到的 JSON 对象的成员;一个对的名称 MUST 序列化为 JSON 字符串,并且 该对的值,即 ActionAffordance 的实例,MUST 序列化为 JSON 对象。

ActionAffordance 实例中的所有 名称-值对,其中名称是包含在 ActionAffordanceInteractionAffordance 的(某个) 签名中的词汇表术语MUST 以该 词汇表术语作为 名称,序列化为由该 ActionAffordance 实例序列化得到的 JSON 对象的成员。

ActionAffordance 实例中赋给 inputoutput 的值 MUST 序列化为 JSON 对象。 它们依赖于 DataSchema,其序列化 在 6.3.10 数据 模式中定义。

ActionAffordance 实例中赋给 forms 的值 MUST 序列化为 JSON 数组, 其中包含一个或多个 JSON 对象序列化, 如 6.3.9 forms 中所定义。

下面给出一个动作可供性的 TD 片段:

6.3.7 events

Thing 实例中,赋给 events 的值是 EventAffordance 实例的映射。 EventAffordance 实例映射的所有名称-值对 MUST 序列化为由该映射序列化得到的 JSON 对象的成员;一个对的名称 MUST 序列化为 JSON 字符串,并且 该对的值,即 EventAffordance 的实例,MUST 序列化为 JSON 对象。

EventAffordance 实例中的所有 名称-值对,其中名称是包含在 EventAffordanceInteractionAffordance 的(某个) 签名中的词汇表术语MUST 以该 词汇表术语作为 名称,序列化为由该 EventAffordance 实例序列化得到的 JSON 对象的成员。

EventAffordance 实例中赋给 subscriptiondatacancellation 的值 MUST 序列化为 JSON 对象。 它们依赖于 DataSchema, 其序列化在 6.3.10 数据 模式中定义。

EventAffordance 实例中赋给 forms 的 值 MUST 序列化为 JSON 数组,其中包含一个或多个 JSON 对象序列化,如 6.3.9 forms 中所定义。

下面给出一个事件对象的 TD 片段:

事件可供性以一种灵活的方式定义, 以便采用现有的(例如 WebSub [websub])或 面向客户的事件机制(例如 Webhooks)。因此, subscriptioncancellation 可以按照所需机制定义。 更多详情请参见 [WOT-BINDING-TEMPLATES]。 示例 A.3 Webhook 事件 示例说明了事件如何使用 subscriptioncancellation 来 描述 Webhooks。

6.3.9 forms

Form 实例中的所有 名称-值对,其中名称是包含在 Form签名中的词汇表术语MUST 以该 词汇表术语作为 名称,序列化为由该 Form 实例序列化得到的 JSON 对象的成员。

如果需要,form 对象 MAY 使用 由前缀标识的、协议特定的词汇表术语进行补充。 另见 8.1.1 协议 绑定

下面给出 forms 数组中 form 对象的 TD 片段:

6.3.9.1 uriVariables

href 也可以携带包含 动态变量的 URI,例如 http://example.org/weather/?lat=35&lon=139 中的 latlon。 在这种情况下,可以按照 [RFC6570] 中定义的方式,将 URI 定义为模板: http://example.org/weather/{?lat,long}

在这种情况下,URI 模板 变量 MUST 收集到 基于 JSON 对象的 uriVariables 成员中, 可以位于物层级,也可以位于 交互可供性层级,并将相关(唯一的) 变量名作为 JSON 名称。

Form 实例中赋给 uriVariables 的 映射里的每个值,其序列化 MUST 依赖于 DataSchema,其 序列化在 6.3.10 数据 模式中定义。

下面给出一个 TD 片段,它在交互 可供性层级中使用 URI 模板来表示查询参数 和 uriVariables

{
    "@context": ["https://www.w3.org/ns/wot-next/td", {
        "htv": "http://www.w3.org/2011/http#"
    }],
    // ...
    "properties": {
        "weather": {
            // ...
            "uriVariables": {
                "lat": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 90,
                    "description": "Latitude for the desired location in the world" },
                "long": {
                    "type": "number",
                    "minimum": -180,
                    "maximum": 180,
                    "description": "Longitude for the desired location in the world" }
            },
            "forms": [{
              "href": "http://example.org/weather/{?lat,long}",
              "htv:methodName": "GET"
            }]
        },
        // ...
    },
    // ...
}

或者,如 [RFC6570] 中所定义, uriVariables 可用于替换 href 结构。下面提供一个示例 TD, 其中获取哥伦比亚波哥大的天气预报的有效请求, 将是发送到 http://example.org/weather/bogota 的 HTTP GET 请求:

{
    "@context": ["https://www.w3.org/ns/wot-next/td", {
        "htv": "http://www.w3.org/2011/http#"
    }],
    // ...
    "properties": {
        "weather": {
            // ...
            "uriVariables": {
                "city": {
                    "type": "string",
                    "description": "City name to find the weather information for"
                }
            },
            "forms": [{
                "href": "http://example.org/weather/{city}",
                "htv:methodName": "GET"
            }]
        },
        // ...
    },
    // ...
}

下面两个示例也可以组合,同时 使用同一个 uriVariables 特性。一个发送到 http://example.org/weather/bogota/?unit=Celsius 的 HTTP GET 请求可以描述如下:

{
    "@context": ["https://www.w3.org/ns/wot-next/td", {
        "htv": "http://www.w3.org/2011/http#"
    }],
    // ...
    "properties": {
        "weather": {
            // ...
            "uriVariables": {
                "city": {
                    "type": "string",
                    "description": "City name to find the weather information for"
                },
                "unit": {
                    "type": "string",
                    "enum": ["fahrenheit_value","celsius_value"],
                    "description": "Desired unit for the temperature value"
                }
            },
            "forms": [{
                "href": "http://example.org/weather/{city}/{?unit}",
                "htv:methodName": "GET"
            }]
        },
        // ...
    },
    // ...
}

uriVariables 主要用于属性 和事件。在改造现有系统时,可能 有必要将 uriVariables 用于 动作。一般而言,在设计新的 基于 WoT 的系统时,建议尽量避免使用 uriVariables

6.3.9.2 contentType

contentType 成员用于指定 媒体类型 [RFC2046], 包括由 ; 字符分隔的属性-值对形式的 媒体类型参数。示例:

{
    // ...
    "contentType": "text/plain; charset=utf-8",
    // ...
}
6.3.9.3 response

在某些用例中,交互 可供性的 form 元数据不仅描述请求, 还为预期响应提供元数据。例如, 动作 takePhoto 定义了一个 input 模式,用于以 JSON 作为 请求负载(即 "contentType": "application/json")来提交相机的参数设置 (光圈优先、定时器等)。该动作的输出 是拍摄的照片,例如以 JPEG 格式提供。 在这种情况下,response 成员 用于指示响应负载的表示格式(例如 "contentType": "image/jpeg")。此处不需要 output 模式,因为内容类型已经完整指定了 表示格式。

下面基于上文描述的 takePhoto 动作,展示带有 response 成员的 form 片段:

{
    // ...
    "actions": {
        "takePhoto": {
            // ...
            "forms": [{
                "op": "invokeaction",
                "href": "http://camera.example.com/api/snapshot",
                "contentType": "application/json",
                "response": {
                    "contentType": "image/jpeg"
                }
            }]
        }
    },
    // ...
}

在预期响应不包含负载、因此也没有 contentType 的情况下, 可以使用空的 response 对象 来传达此信息。

{
    // ...
    "actions": {
        "brewCoffee": {
            "description": "Invoking this action does not return a payload.",
            "input": {
              "type": "object",
              "properties": {
                "coffeeType": {
                  "enum": [
                    "espresso",
                    "americano",
                    "cappuccino",
                    "latte"
                  ]
                },
                "useOatMilk": {
                  "type": "boolean",
                  "default": false
                }
              },
              "required": [
                "coffeeType"
              ]
            },
            "forms": [{
                "op": "invokeaction",
                "href": "http://coffee-maker.example.com/brew-coffee",
                "contentType": "application/json",
                "response": {}
            }]
        }
    },
    // ...
}
6.3.9.4 additionalResponses

在某些情况下,作为交互 可供性一部分从物接收的消息,可能会由于不同原因而有所不同。 这些原因可能是错误情况,或是对有效响应的 替代响应。在这些情况下,可以使用 additionalResponses 术语来 描述这种行为。

例如,用于启动汽车发动机的动作可供性, 在恶劣天气条件下或发动机需要维护时可能无法工作。 在这种情况下,物需要使用通常不会 使用的负载进行回复。

下面展示一个在动作 可供性中带有 additionalResponses 成员的 TD 片段。其第一个元素说明了 上述情况:错误响应可以使用不同于 output 中所描述内容的另一种负载发送。 值为 falsesuccess 表明该负载对应错误情况,而 schema 允许链接到 schemaDefinitions 中使用的负载描述。 additionalResponses 中的第二个元素 也描述了错误响应,但这次响应没有 负载。

{
    // ...
    "schemaDefinitions": {
      "actionErrorPayload": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "enum": ["cold","hot","maintenance"]
          },
          "timeStamp": {
            "description": "UNIX time in numbers indicating when the error happened",
            "type": "number"
          }
        }
      }
    },
    // ...
    "actions": {
        "startEngine": {
            "output": {
              "type": "string"
            },
            "forms": [{
                "op": "invokeaction",
                "href": "http://mycar.example.com/api/engine",
                "contentType": "application/json",
                "additionalResponses": [
                  {
                    "success": false,
                    "contentType": "application/json",
                    "schema": "actionErrorPayload"
                  },
                  {
                    "success": false
                  },
                ]
            }]
        }
    },
    // ...
}

additionalResponses 术语也可以用于 非错误情况。在这种情况下, success 被设置为 true, 并且可以使用另一个 schema 来描述负载。

6.3.9.5 contentMediaTypecontentEncoding

在某些情况下,二进制数据会嵌入到基于文本的 值中,例如,基于 JSON 字符串的值嵌入了一个 base64 编码图像。术语 contentMediaTypecontentEncoding 可用于阐明 这类名称-值对的上下文和编码格式。 下面展示 contentMediaTypecontentEncoding 的使用样例:

{
    // ...
    "properties": {
        "image": {
                "description": "Provides latest image",
                "type": "string",
                "contentMediaType": "image/png",
                "contentEncoding": "base64",
                "forms": [{
                            "op": "readproperty",
                            "href": "coaps://mylamp.example.com/lastPicture",
                            "cov:methodName": "GET",
                            "contentType": "application/json"
                    }]
        }
    },
    // ...
}
6.3.9.6 顶层 forms

forms 出现在顶层时, 它可用于描述由提供的元交互。 例如,操作类型 readallpropertieswriteallproperties 用于与进行元交互, 通过这些交互,消费者可以一次性读取、写入 或观察所有属性。在下面的示例中, forms 成员包含在 TD 根 对象中,消费者可以同时使用提交目标 https://mylamp.example.com/properties 来读取或写入该的所有属性 (即 onbrightnesstimer), 并在单个协议事务中完成。

{
    // ...
    "properties": {
        "on": {
            "type": "boolean",
            "forms": [...]
        },
        "brightness": {
            "type": "number",
            "forms": [...]
        },
        "timer": {
            "type": "integer",
            "forms": [...]
        }
    },
    // ...
    "forms": [{
        "op": "readallproperties",
        "href": "https://mylamp.example.com/properties",
        "contentType": "application/json",
        "htv:methodName": "GET"
    },
    {
        "op": "writeallproperties",
        "href": "https://mylamp.example.com/properties",
        "contentType": "application/json",
        "htv:methodName": "PUT"
    }]
}

物层级的 uriVariables 可在此处用于 为操作提供更多变量,或为 readmultipleproperties 操作指定 属性可供性名称列表。在下面的示例中, 属性的单位可以通过这样的变量来设置, 并且可以设置期望的属性列表:

{
    // ...
    "properties": {
        "temperature": {
            "type": "number",
            "forms": [...]
        },
        "brightness": {
            "type": "number",
            "forms": [...]
        },
        "humidity": {
            "type": "integer",
            "forms": [...]
        }
    },
    "uriVariables": {
        "propertyNames": {
            "type": "string",
            "description": "Comma separated list of property names to select."
        },
        "unitSystem": {
            "type": "string",
            "enum": ["metric","imperial","uscustomary"],
            "description": "System of Measurement that will be used for the values"
        }
    },
    "forms": [{
        "op": "readallproperties",
        "href": "https://mything.example.com/properties{?unitSystem}",
        "contentType": "application/json",
        "htv:methodName": "GET"
    },
    {
        "op": "readmultipleproperties",
        "href": "https://mylamp.example.com/properties{?propertyNames,unitSystem}",
        "contentType": "application/json",
        "htv:methodName": "GET"
    }]
}

对于 readmultipleproperties 操作, 发送到 URI https://mylamp.example.com/properties?propertyNames=humidity,temperature&unitSystem=metric 的一个示例 HTTP GET 请求,将返回 humiditytemperature 属性可供性的值,并使用 metric 度量系统。

对于操作类型 writeallproperties,预期 消费者提供所有 可写(非 readOnly)属性以及 (新的)赋值(例如在负载中)。类似地, 对于 writemultipleproperties 操作 类型,预期消费者提供可写 (非 readOnly)属性。在侧,对于 readmultiplepropertiesreadallproperties 操作类型,预期返回 可读(非 writeOnly)属性。

6.3.10 数据模式

通过 DataSchema 定义的 WoT 物描述数据模式,基于 JSON Schema 术语的一个子集 [JSON-SCHEMA]。 因此,TD 数据模式的序列化可以直接输入到 JSON Schema 验证器实现中,用于 验证与交换的数据。

数据模式序列化适用于 PropertyAffordance 实例、赋给 ActionAffordance 实例中 inputoutput 的值、赋给 EventAffordance 实例中 subscriptiondatacancellation 的值,以及 InteractionAffordance子类实例中 赋给 uriVariables 的值(当form 对象使用 URI 模板时)。

DataSchema 的某个子类实例中的所有 名称-值对,其中名称是包含在该子类签名中,或包含在 DataSchema签名中的词汇表术语MUST 以该 词汇表术语作为 名称,序列化为由该 DataSchema 子类实例序列化得到的 JSON 对象的成员。

ObjectSchema 实例中赋给 properties 的值 MUST 序列化为 JSON 对象。

DataSchema 实例中赋给 enumrequiredoneOf 的值 MUST 序列化为 JSON 数组。

ArraySchema 实例中赋给 items 的值 MUST 序列化为 JSON 对象,或包含 JSON 对象的 JSON 数组。

下面给出一个 TD 片段数据模式成员。注意, 周围对象可以是数据模式对象 (例如用于 inputoutput),也可以是 属性对象,后者会包含附加 成员。

术语 readOnlywriteOnly 可用于指示哪些数据 项在读取交互中交换(即读取 属性时),以及哪些在写入交互中交换(即 写入属性时)。当非常规的属性在 读取和写入时表现出不同数据时,这可作为一种权宜方法; 这种情况可能出现在用物描述来增强 现有设备或服务时。

下面给出一个使用 readOnlywriteOnly 的 TD 片段:

{
    // ...
    "properties": {
        "status": {
            "description": "Read or write On/Off status.",
            "type": "object",
            "properties": {
                "latestStatus": {
                    "type": "string",
                    "enum": ["on_value", "off_value"],
                    "readOnly": true
                },
                "newStatusValue": {
                    "type": "string",
                    "enum": ["on_value", "off_value"],
                    "writeOnly": true
                }
            },
            "forms": [...]
        }
    }
    // ...
}

当读取 status 属性时, 状态数据会使用负载中的 latestStatus 成员返回。要更新 status 属性,必须通过负载中的 newStatusValue 成员提供新值。

作为一项附加特性,物描述实例 允许在数据模式内使用 unit 成员。 这可用于将计量单位关联到 数据项。其字符串值可以自由选择。 然而,建议选择在知名词汇表中定义的单位。有关 示例,见 7. TD 上下文扩展

6.4 标识

物描述的基于 JSON 的序列化由 媒体类型 application/td+json 或 CoAP Content-Format ID 432 标识(见 13. IANA 考量)。

6.5 验证

在若干上下文中,对物描述的基于 JSON 的 序列化进行自动验证是有用的。形式上, 有效的 TD 满足本规范中的所有断言, 但并非所有断言都能仅根据 JSON 序列化进行验证,例如,列在 9. 行为断言下、 将 TD 与其所描述物的行为相关联的断言。扩展也 存在问题,因为即便给出了用于验证某个 扩展的形式化元数据,在部署中动态获取这些 元数据也可能带来隐私风险。因此,在本 节中,我们命名并定义适用于不同上下文的 各种验证级别。

6.5.1 最小验证

这一验证级别包括本文档中规范性表格所隐含的 所有断言,以及那些仅查看 TD 本身即可 检查的断言。

最小验证适用于验证需要自包含的场景 (例如,隔离网络上的设备)。 它不会尝试验证上下文扩展和 词汇表。

实践中,可以使用 JSON Schema 结合少量抽查来验证这些断言, 例如检查安全模式名称是否具有匹配的 定义。

6.5.2 基本验证

这一验证级别包括 6.5.1 最小 验证所涵盖的全部内容,以及对语义 定义的基本验证。

基本验证适用于网络访问可用且不会造成隐私 风险,并且计算需求相对不受限制的情况。 例如,它适用于网关,但不适用于端点, 因为需要语义处理。它可以对扩展进行基本验证, 具体来说,是验证所使用的词汇表已被定义。

在这种情况下,可以使用上下文定义文件和 SHACL 定义来验证附加断言,并检查 TD 的语义一致性。 此外,如果能够获取扩展词汇表的上下文定义和 SHACL 约束,那么这些也可用于 验证扩展。

6.5.3 完整验证

完整验证确认本文档中的所有断言均已满足, 包括 9. 行为断言中给出的、 用于确认 TD 与其所描述的物一致的断言。

这一验证级别适用于开发期间、发布之前, 以及可能在安装之后。开发期间的验证必须 在测试物上进行。此类物的实例实际安装时, 需要使用适当的每实例标识符和 URL 更新 TD, 因此为了获得最大保证,现场验证必须在安装 之后进行。

7. TD 上下文扩展

本节是非规范性的。

除了 5. TD 信息模型中的标准 词汇表定义之外, WoT 物描述还提供了从附加命名空间添加上下文 知识的可能性。该机制可用于通过附加 (例如特定领域的)语义来丰富物描述实例。 它也可用于在将来导入附加的协议绑定或新的 安全方案。

对于此类TD 上下文 扩展,物描述使用 JSON-LD [json-ld11] 中已知的 @context 机制。 使用TD 上下文 扩展时, Thing @context 值是一个 数组,其中包含类型为 anyURI 的附加元素 用于标识 JSON-LD 上下文文件,或包含按 5.3.1.1 Thing中定义的命名空间 IRI 的 映射

6.1 到 JSON 类型的映射中针对复杂类型的序列化规则定义了 扩展 @context 名称-值 对的序列化。下面给出一个带有TD 上下文扩展的片段:

{
    "@context": [
        "https://www.w3.org/ns/wot-next/td",
        {
            "eg": "http://example.org/iot#",
            "cov": "http://www.example.org/coap-binding#"
        },
        "https://schema.org/"
    ],
    // ...
}

7.1 语义标注

TD 上下文扩展允许在 物描述实例中使用附加的 词汇表术语。 如果包含的命名空间基于 RDF Schema 或 OWL 所提供的那些 定义,则可以通过将实例关联到 这样一个外部 定义,来对物描述的任何实例进行语义标注。 这是通过向 @type 名称-值对赋予一个名称,或在其数组值中包含名称以表示多个 关联/标注来完成的。按照 6.1 到 JSON 类型的映射中的序列化规则,@type 会被序列化为 JSON 字符串或 JSON 数组。@type 是 JSON-LD 关键字 [json-ld11],用于设置节点的类型。

TD 上下文扩展还允许在物 描述的任何实例内包含附加的 名称-值对和明确定义的值。这些对和值 通过所包含的词汇表术语定义,并分别 序列化为相应 JSON 对象中的附加成员,或现有成员的值。 示例包括的附加版本元数据,或数据 项的计量单位。

接下来的小节展示了物描述中不同 类型本体的一些使用样例。

7.1.1 示例 I:附加 基本元数据

下面的示例 TD 片段提供了来自 @context 中所给不同外部上下文文件的附加元数据 术语。版本信息容器通过添加所用软件的 附加版本信息(s:softwareVersion)得到扩展。schema.org 用于提供 序列号和组织信息,例如该的公司名称。 SAREF 本体用于提供该的语义上下文 (saref:TemperatureSensor),而对于 temperature 属性的单位 赋值,则使用 Ontology of Units of Measure (OM)

请注意,这些词汇表和 本体用作示例。可以根据应用领域和用例 使用其他词汇表和本体。

{
    "@context": [
        "https://www.w3.org/ns/wot-next/td",
        {
            "saref": "https://w3id.org/saref#",
            "om": "http://www.ontology-of-units-of-measure.org/resource/om-2/",
            "schema": "https://schema.org"
        }
    ],
    "version": {
        "instance": "1.2.1",
        "schema:softwareVersion": "1.0.1"
    },
    "schema:serialNumber": "4CE0460D0G",
    "schema:manufacturer": {"name": "CompanyName"},
    // ...
    "@type": "saref:TemperatureSensor",
    "properties": {
        "temperature": {
            "description": "Temperature value of the weather station",
            "type": "number",
            "minimum": -32.5,
            "maximum": 55.2,
            "unit": "om:degreeCelsius",
            "forms": [...]
        },
        // ...
    },
    // ...
}

7.1.2 示例 II:状态 标注

在许多情况下,TD 上下文扩展可 用于标注数据模式的若干部分,以便能够 对物理世界对象的状态信息进行语义处理, 这些状态信息由交互期间交换的数据表示 (例如在响应负载中)。例如, 可以在TD 文档中嵌入 对该状态信息的 RDF 语义描述,并且 可以将数据模式的各个部分分别标注为引用 该 RDF 建模的物理世界对象状态的特定部分。

下面的 TD 片段使用 SAREF 来描述 一盏灯的状态。外部词汇表术语 ssn:forProperty 取自 SSN,即 Semantic Sensor Network Ontology [VOCAB-SSN], 用于将 status 属性的数据模式与物理 世界对象的实际开/关状态相链接。

{
    "@context": [
        "https://www.w3.org/ns/wot-next/td",
        {
            "saref": "https://w3id.org/saref#",
            "ssn": "http://www.w3.org/ns/ssn/"
        }
    ],
    "id": "urn:uuid:67c9122b-2680-4e1a-b41c-5af07edba1f4",
    "@type": "saref:LightSwitch",
    "saref:hasState": {
        "@id": "urn:uuid:67c9122b-2680-4e1a-b41c-5af07edba1f4/state",
        "@type": "saref:OnOffState"
    },
    // ...
    "properties": {
        "status": {
            "ssn:forProperty": "urn:uuid:67c9122b-2680-4e1a-b41c-5af07edba1f4/state",
            "type": "string",
            "forms": [{"href": "https://mylamp.example.com/status"}]
        },
        "fullStatus": {
            "ssn:forProperty": "urn:uuid:67c9122b-2680-4e1a-b41c-5af07edba1f4/state",
            "type": "object",
            "properties": {
                "statusString": { "type": "string" },
                "statusCode": { "type": "number" },
                "statusDescription": { "type": "string" }
            },
            "forms": [{"href": "https://mylamp.example.com/status?full=true"}]
        },
        // ...
    },
    // ...
}

示例 2中, 的状态由 status 可供性本身给出,而可能的状态 变化由 toggle 可供性给出。换言之, 物理世界对象的状态直接提供了该交互 可供性。这种设计对于简单情况是令人满意的。 然而,在更复杂的情况下,同一物理状态可能有 多个可供性可用。在上面的示例中, fullStatus 属性为该灯的状态提供了一个 替代的、更详细的表示。

7.1.3 示例 III:地理位置 标注

对于建筑、农业或 智慧城市等许多用例,需要基于位置的数据。 这些信息可以在物描述中以 不同方式提供,并且可根据用途(例如室内、室外) 依赖不同类型的位置本体(例如 [w3c-basic-geo]、 schema.org)。另见 [sdw-bp]。

下面的 TD 片段使用 [w3c-basic-geo] 本体中的 latlong,在物的顶层提供静态纬度和经度 元数据。

{
    "@context": [
        "https://www.w3.org/ns/wot-next/td",
        {
            "geo": "http://www.w3.org/2003/01/geo/wgs84_pos#"
        }
    ],
    "@type": "Thing",
    "geo:lat": "26.58",
    "geo:long": "297.83",
    // ...
    "properties": {
        // ...
    }
}

在某些用例中,基于位置的元数据必须 在交互层级提供,例如作为一个返回 基于 schema.org 的最新 longitudelatitudeelevation 值的 属性提供:

{
    "@context": [
        "https://www.w3.org/ns/wot-next/td",
        {
            "schema": "https://schema.org#"
        }
    ],
    // ...
    "properties": {
        "position": {
            "type": "object",
            "@type": "schema:GeoCoordinates",
            "properties": {
                    "longitude": { "type": "number" },
                    "latitude":  { "type": "number" },
                    "elevation": { "type": "number" }
            },
            "forms": [{"href": "https://robot.example.com/position"}]
        },
        // ...
    },
    // ...
}

如果数据模型中希望对例如 longitudelatitudeelevation 使用不同名称, 则可以使用 jsonld:context 将术语链接到某个本体中的 特定词汇表(另见 [JSON-SCHEMA-ONTOLOGY], 第 3.3 节“为数据 实例定义 JSON-LD 上下文”):

{
    "@context": [
        "https://www.w3.org/ns/wot-next/td",
        {
            "schema": "https://schema.org#"
        }
    ],
    // ...
    "properties": {
        "position": {
        "jsonld:context": {
            "schema": "https://schema.org/",
            "long": "schema:longitude",
            "lat": "schema:latitude",
            "height": "schema:elevation"
        },
        "type": "object",
        "properties": {
            "long": { "type": "number" },
            "lat": { "type": "number" },
            "height": { "type": "number" }
        }
        }
    },
    // ...
}

7.2 添加绑定

借助物描述中的TD 上下文扩展,可以通过来自 WoT Binding Registry [WOT-BINDING-REGISTRY] 的绑定 规范来补充通信元数据, 这些绑定规范通过附加词汇表术语添加,并被序列化 到表示 Form 实例的 JSON 对象中。 更多信息请见 8. 绑定

7.3 添加安全方案

最后,未包含在 5.3.3 安全 词汇表 定义中的新安全方案,可以使用TD 上下文扩展 机制导入。此示例使用一个虚构的 ACE 安全方案, 该方案基于 [RFC9200], 并且在此示例中由位于 http://www.example.org/ace-security# 的命名空间定义。 附加安全方案 MUST SecurityScheme子类

{
    "@context": [
        "https://www.w3.org/ns/wot-next/td",
        {
            "cov": "http://www.example.org/coap-binding#",
            "ace": "http://www.example.org/ace-security#"
        }
    ],
    // ...
    "securityDefinitions": {
        "ace_sc": {
            "scheme": "ace:ACESecurityScheme",
            // ...
            "ace:as": "coaps://as.example.com/token",
            "ace:audience": "coaps://rs.example.com",
            "ace:scopes": ["limited", "special"],
            "ace:cnonce": true
        }
    },
    "security": ["ace_sc"],
    "properties": {
        "status": {
            // ...
            "forms": [{
                "op": "readproperty",
                "href": "coaps://rs.example.com/status",
                "contentType": "application/cbor",
                "cov:methodName": "GET",
                "ace:scopes": ["limited"]
            }]
        }
    },
    "actions": {
        "configure": {
            // ...
            "forms": [{
                "op": "invokeaction",
                "href": "coaps://rs.example.com/configure",
                "contentType": "application/cbor",
                "cov:methodName": "POST",
                "ace:scopes": ["special"]
            }]
        }
    },
    // ...
}

请注意,5.3.3 安全词汇表 定义中定义的所有安全方案已经是 TD 上下文的一部分, 不需要通过TD 上下文扩展包含。

8. 绑定

从消费者发送到物以及从物返回的每条消息, 尽管有 WoT 提供的属性–动作–事件抽象, 仍然需要通过网络协议传输。Forms 层级中的 操作需要绑定到消息在网络上应当呈现的形式。 因此,WoT 物描述中的每个 form 都需要有一个提交目标, 该目标由 href 成员给出,如 Form 中所示。例如,如果目标 以 httphttps 开头,消费者可以推断该 实现了 基于 HTTP 的协议绑定, 并且应当预期在此 form 的实例中出现 HTTP 特定术语。更多说明和示例见 8.1.1 协议绑定

此外,由可供性层级中的数据模式描述的负载 需要被序列化为某种数据格式,并通过网络协议发送。 与操作绑定到协议消息的方式类似, 数据模式会绑定到由 contentTypeForm 中提供的协议特定术语 指示的数据格式。根据这些术语,消费者 可以推断所需的序列化方法,并将应用层数据 转换为要在网络协议上传输的数据。类似地, 对于来自的消息,消费者可以反序列化数据 并将其呈现给应用层。例如,一个用 Python 实现的消费者 可以读取 application/json 作为 contentType 的值,并将 Python dictionary 数据 结构序列化为 JSON 对象。更多说明和示例见 8.1.2 负载绑定

上述机制在 Web of Things 中称为绑定, 一个具体示例在 5 中通过一个机器人手臂的 TD 摘录来说明,其中包含 HTTP 和 JSON 绑定。在这里,消费者 打算调用机器人手臂的一个动作 (goTo),以便将其移动到 x 等于 12 且 y 等于 100 的位置。为此,它会创建正确的 负载,对其进行序列化,并使用正确的协议 选项发送。物通过网络接收消息,并 以与其 TD 对应的消息进行响应。其他 协议、负载格式和/或它们的组合也是 可能的,并在 8.1 绑定 机制中解释。

Bindings mechanism with a TD, Thing and Consumer
5 TD 摘录内部的绑定机制, 包含其物和消费者的消息。

总之,绑定使物描述能够以特定方式适配 某个特定协议、数据负载格式,或二者同时适配。 这是通过 URI 方案、附加描述性词汇表、物模型和示例来完成的, 其目标是同时指导物和消费者的实现者。 本节解释整体机制,并给出创建新绑定的基本指导。 [WOT-BINDING-REGISTRY] 包含现有绑定的注册表(列表),以及向该 注册表注册新条目所需遵循的要求。

在为某个特定 IoT 设备生成 TD 时, 可以使用相应的绑定来查找需要在物 描述中提供的通信元数据。6 展示了绑定的使用方式。 基于协议或媒体类型,会创建一个 TD。 处理 TD 的消费者通过包含相应的协议栈和媒体类型编码器/解码器, 并根据 TD 中给出的信息(例如消息的序列化格式和 header 选项) 配置该栈(或其消息),来实现 TD 中存在的所需绑定。

Protocols, Media Types, and their combinations, as building blocks for TDs
6 协议、媒体类型及其 组合,作为 TD 的构建块

本规范的编辑还建议阅读 [WOT-ARCHITECTURE] 中的相关章节, 例如 WoT Binding Templates 构建块 超媒体控件 协议绑定媒体 类型

8.1 绑定机制

8.1.1 协议绑定

[WOT-THING-DESCRIPTION] 定义了抽象操作,例如 readpropertyinvokeactionsubscribeevent,这些操作描述了执行 物描述中 form 所描述操作的预期语义。为了在可供性上 执行这些操作,需要将操作绑定到协议。 换言之,form 需要包含消费者例如通过该 form 中的协议读取属性所需的 全部信息。

大多数协议都有一组相对较小的方法, 这些方法定义消息类型,即消息的语义意图。 REST 和 PubSub 架构模式会产生具有不同方法的 不同协议。每个目标协议都可能为类似操作指定不同的方法名称, 并且不同协议中类似方法名称之间可能存在语义差异。 此外, 可能使用不同方法来执行某个特定 WoT 操作。例如,一个物可以使用 HTTP POST 请求 执行 writeproperty 操作, 而另一个物可以使用 HTTP PUT。由于这些原因, 物描述需要能够按操作指定要使用的方法。

REST 和 PubSub 协议中常见的方法包括 GET、PUT、POST、DELETE、PUBLISH 和 SUBSCRIBE。 绑定规范描述了这些现有方法及其相关词汇表如何在 物描述中使用,以 绑定到 WoT 操作。这是通过定义协议的 URI 方案,并将协议方法映射到诸如 readpropertyinvokeactionsubscribeevent 等抽象 WoT 操作来完成的。 在某些情况下,还会提供附加说明,以解释 在不同协议使用场景下应如何使用词汇表术语。

下面的示例展示了 HTTP 和 Modbus 协议中 readproperty 操作的绑定实例。 请注意,这些只是示例;请始终参考相应的绑定规范, 以了解相关词汇表术语及其 值。

示例 53:将 readproperty 操作绑定到 HTTP 的绑定实例
{
    "href": "http://example.com/props/temperature",
    "op": "readproperty",
    "htv:methodName": "GET"
}
示例 54:将 readproperty 操作绑定到 Modbus 的绑定实例
{
    "href": "modbus+tcp://127.0.0.1:60000/1/4",
    "op": "readproperty",
    "modv:function": "readCoil"
}

上面示例中的 form 元素传达了 以下陈述:

  • 左侧示例:通过向主机 example.com 的端口 80 上的资源 props/temperature 执行 HTTP GET 请求,对主题属性可供性执行 readproperty (根据 [RFC2616],假定使用端口 80)。
  • 右侧示例:使用 Modbus 的 readCoil 函数,对 IP 地址为 127.0.0.1、unitID 为 1、端口为 60000 的设备中 coil 4 上的主题属性可供性执行 readproperty

这些绑定实例及其陈述也适用于其他操作和协议。 下面是 invokeactionsubscribeevent 的示例:

示例 55:将 invokeaction 操作绑定到 HTTP 的绑定实例
{
    "op": "invokeaction",
    "href": "http://192.168.1.32:8081/example/levelaction",
    "htv:methodName": "POST"
}
示例 56:将 subscribeevent 操作绑定到 MQTT 的绑定实例
{
    "op": "subscribeevent",
    "href": "mqtt://iot.platform.com:8088",
    "mqv:filter": "thing1/events/overheating",
    "mqv:controlPacket": "subscribe"
}

上面示例中的 form 元素传达了 以下陈述:

  • 左侧示例:通过向主机 192.168.1.32 的端口 8081 上的资源 example/levelaction 执行 HTTP POST 请求,对主题动作可供性执行 invokeaction
  • 右侧示例:通过连接到 iot.platform.com 的端口 8088 上的 MQTT broker,然后订阅主题 thing1/events/overheating, 对主题事件可供性执行 subscribeevent

在某些情况下,需要包含协议的 header 选项 或其他参数。鉴于这些内容高度依赖于协议, 请参考 Web of Things (WoT) Binding Registry 中列出的绑定。此外, 协议可能已经定义了可用于某些交互类型的子协议。 例如,为了使用 HTTP 接收异步通知, 某些服务器可能支持 long polling(longpoll)、WebSub [WebSub] (websub)以及 Server-Sent Events [eventsource] (sse)。

8.1.1.1 子协议

如 [WOT-ARCHITECTURE] 中所定义, 子协议是协议的一种扩展机制。子协议可以要求 一系列协议消息,或要求消息负载具有特定结构, 这些负载在该子协议内部可以具有自己的语义。 子协议的使用通过 subprotocol 字段表示,如 [WOT-THING-DESCRIPTION] 中所定义。它可以用于 form 实例中,以指示 使用这些协议之一,例如具有特殊 HTTP 用法的 long polling:

示例 57: 订阅事件时的子协议用法
{
    "op": "subscribeevent",
    "href": "https://mylamp.example.com/overheating",
    "subprotocol": "longpoll"
}

subprotocol 术语可取的值 不受 [WOT-THING-DESCRIPTION] 约束,因为不同协议可以具有不同的 子协议。相应地,子协议与其所扩展的协议相关联, 并且应与 forms 的 href (或 base)中指示的协议一起理解。 对于 WebSockets,可以使用 IANA 注册的 Websocket 子协议 [iana-web-socket-registry]。 对于 CoAP,可以使用 "subprotocol":"cov:observe" 来描述 [RFC6741] 所定义的异步观察操作。 子协议可以作为协议绑定 规范的一部分进行定义和解释。

8.1.1.2 将物描述与 协议绑定一起使用

协议绑定规范包含的词汇表会扩展 [WOT-THING-DESCRIPTION] 中的词汇表。这意味着 TD 被消费的方式,以及与物发生交互的方式, 会适配这些词汇表。下面的步骤解释了这一过程 通常是什么样的。

  1. 检测协议:在激活 form 以执行操作时, 消费者 SHOULD 查看 href 成员以及 base (如果存在),并识别协议。
  2. 选择正确的协议栈: 消费者 SHOULD 从其协议软件栈中选择 正确协议。
  3. 验证 TD 的 forms 部分:使用相应 绑定规范中提供的 JSON Schema 实例,或通过以编程方式 检查键值对,消费者 MAY 验证相应的 form 术语, 以确认它们在 TD 实例中被正确指定。
  4. 开始通信:消费者 SHOULD 按照 form 所指定的内容 以及预期的附加行为,为所选择的操作发送请求。 这些内容使用不同的 form 术语指定,例如 subprotocol 或协议绑定引入的其他词汇表术语。 与物交换的交互可供性数据 SHOULD 符合 TD 中存在的数据模式内容类型。 与操作对应的数据模式可在表 28 中找到。

因此,以下要求适用于物和消费者:

  • WoT 物描述中的每个 form MUST 遵循 其 href 成员的 URI 方案 [RFC3986] 所指示的协议绑定的要求。
  • WoT 物描述中的每个 form MUST 准确 描述在一次 交互中接受的请求(包括请求 header,如果 存在)。

8.1.2 负载绑定

[WOT-THING-DESCRIPTION] 定义了两种机制,用于描述通过任何协议传输的消息负载 可以是什么样的。首先,媒体类型 [IANA-MEDIA-TYPES] 描述了通过协议发送和接收数据所使用的 序列化方式。它们在 TD 的 Forms 中通过 contentType 表示,该术语对每个交互可供性都是 强制的。其次,它定义了数据模式概念,用于描述 与媒体类型一起使用的消息结构。 二者的组合允许在 TD 中描述任何消息, 从而使物和消费者能够正确地序列化和 反序列化消息。

在本节余下的 8.1.2.1 内容 类型8.1.2.2 数据 模式中,可以看到负载绑定可能呈现形式的示例。

8.1.2.1 内容类型

内容类型包括媒体类型以及媒体类型可能具有的参数, 并使序列化文档能够被正确处理。这样, 消息就可以以任意格式交换,并允许应用的上层 适配不同格式。在某些情况下,例如图像、视频或任何 非结构化数据,内容类型足以描述负载; 但在 JSON([RFC8259]) 等情况下,通常会提供数据模式,如 8.1.2.2 数据 模式中所解释。

例如,一个数字负载可以分别序列化为 JSON 或 XML,并在 forms 的 contentType 中分别以 application/jsonapplication/xml 指示。还可以通过加号 (+)或分号(;)记法进行进一步 参数化。

在下面的示例中,可以看到带有 JSON 和 plain text 内容类型及附加参数的 form 元素。在此特定情况下, 这些 forms 描述了使用 httpcoap 读取该属性会产生 不同内容类型。对于结构化媒体类型,通常会在可供性层级 提供数据模式,如 8.1.2.2 数据 模式5.3.2 数据模式 词汇表定义中所解释。然而,对于图像和视频等非结构化 数据,通常没有可用的数据模式。

示例 58:forms 中的 JSON 和 CBOR 媒体类型
{
    "forms":[
    {
        "href": "http://example.com/properties/temperature",
        "op": "readproperty",
        "contentType": "application/json"
    },
    {
        "href": "coap://example.com/properties/temperature",
        "op": "readproperty",
        "contentType": "text/plain;charset=utf-8"
    }]
}

其他内容类型也可以在 TD 中表达。 在下面的列表中,可以找到不同内容类型变体的示例。 这些内容类型可以替换 示例 58中的内容类型。

  • 不带参数化的结构化内容类型
  • 带参数化的结构化内容类型
    • application/senml+json:以 JSON 序列化的 SenML 数据 [RFC8259]
    • application/senml+xml:序列化为 XML 的 SenML 数据
    • application/ocf+cbor:以 CBOR 序列化的 OCF 负载
    • text/csv;charset=utf-8:以 UTF-8 编码的 CSV [RFC4180]
  • 非结构化内容类型
    • image/jpeg:JPEG 图像
    • video/mp4:MP4 视频
    • application/octet-stream:通用 二进制流
8.1.2.2 数据模式

5.3.2 数据模式 词汇表定义中所解释,数据模式描述 与媒体类型一起使用的消息结构。 虽然它在很大程度上受到 JSON Schema [json-schema] 启发,但它也可用于描述其他负载类型,例如 [XML]、 字符串编码的图像、整数的位表示等。 除媒体类型之外,还 SHOULD 使用数据模式。

根据具体情况,消息结构可以是从简单数字到 数组,或具有多层嵌套的对象等任何形式。 现有 IoT 平台和标准具有某些负载格式, 并且数据结构方式有所变化。如 5.3.2 数据模式 词汇表定义中所解释,数据模式可以在 TD 的以下位置之一使用:

  • 属性可供性:每个属性 可供性可以包含数据模式术语,并 描述读取、观察或写入时的属性值。
  • 动作可供性:inputoutput 词汇表术语用于 在双向交换数据时提供两个不同的模式, 例如调用带输入参数的动作可供性并接收 状态信息的情况。
  • 事件可供性:datadataResponsesubscriptioncancellation 分别用于描述由暴露物传递事件数据时的 负载、事件传递时用于回复的负载、 订阅事件所需的负载,以及取消从暴露物 接收事件数据所需的负载。
  • URI 变量:在物或可供性 层级中,uriVariables 可以描述 需要以字符串形式提供在请求 URI 内的数据。

下面是一个简单 JSON 对象负载 及其相应数据模式的示例。来自各种 IoT 平台和标准的示例可在 E. 来自 IoT 平台和标准的负载与数据模式 示例中找到。

示例 59:简单 JSON 对象 负载
{
    "level": 50,
    "time": 10
}
示例 60:简单 JSON 对象负载的 DataSchema
{
    "type": "object",
    "properties": {
        "level": {
            "type": "integer",
            "minimum": 0,
            "maximum": 255
        },
        "time": {
            "type": "integer",
            "minimum": 0,
            "maximum": 65535
        }
    }
}

8.1.3 协议和负载 绑定

在 IoT 平台或 OPC-UA、BACnet 等标准中, 可以指定协议、媒体类型和数据结构。在这些情况下, 其绑定 规范可以依赖一组8.1.1 协议绑定8.1.2 负载绑定,也可以 同时指定 协议、媒体类型和数据结构。

在 IoT 平台中,可能存在同时使用 HTTP 与特定 JSON 负载结构的要求。 因此,相应的绑定 规范会提供物模型和 TD 示例, 以允许对多个绑定进行语义分组。 这首先需要有一个用于 HTTP 和 JSON 的 绑定 规范

在 OPC-UA 或 BACnet 等标准中,绑定 规范包含关于协议和 媒体类型的要求,也可能包含关于数据结构的要求。 因此,该 绑定 规范本身就足以指定 绑定实例 应当是什么样子。

8.2 与配置文件的关系

Web of Things 还定义了一种配置文件机制, 允许降低实现工作量。配置文件构建在现有绑定之上, 通过约束 TD 的灵活性来实现。这类约束可以是绑定、 语义上下文、链接关系、安全方案和 发现机制。通过这些约束,它们在绑定之上提供了 附加的互操作性保证。

编辑者注

目前在 [WOT-PROFILES] 中规定的配置文件机制 并不完全遵循上述机制。不过, 对于配置文件机制的未来方向已有共识。 一旦配置文件机制得到更新,本节将相应更新。

例如,一个配置文件可以约束 readproperty 操作使用 HTTP GET 方法,并要求负载始终序列化为 JSON。 配置文件的使用由 TD 中的 profile 术语指示, 该术语是一个指向配置文件定义的 URI。 消费者如何使用配置文件,在 [WOT-PROFILES] 规范的配置文件 机制一节中解释。

9. 行为断言

以下断言涉及 WoT 系统组件的行为, 而不是 TD 的表示或信息模型。不过, 请注意 TD 是描述性的,尤其可以用于描述 已存在的网络接口。在这些情况下,不能作出 约束这类已存在接口行为的断言。 相反,这些断言应被解释为对 TD 准确表示 这类接口的约束。

9.1 安全配置

为了实现安全互操作,安全配置 需要准确反映的要求:

某些安全协议可能会动态请求认证 信息,包括所需的编码或加密方案。 上述要求的一个结果是,如果某个协议请求了物描述中未声明的 安全凭证形式,或请求了未声明的编码或加密方案, 则该物描述应被视为 无效。

9.2 数据模式

TD 中提供的数据模式应准确表示所描述 在 TD 中指定的交互中返回和接受的数据负载。 一般而言,消费者应严格遵循 数据模式,不生成 WoT 物描述中未给出的任何内容, 但应接受来自的、 WoT 物描述中未显式给出的附加数据。一般而言, 由 WoT 物描述进行描述, 但消费者在与交互时 被约束为遵循 WoT 物描述。

10. 物 模型

10.1 基本概念

下图说明物模型物 描述之间的关系。物模型主要描述 交互可供性,例如属性动作事件,以及公共元数据。 当一个物 描述依赖物模型被实例化时, 它 SHOULD 根据该 物模型是有效的。 这一范式可以与面向对象编程中 用于创建对象(~物描述)的抽象类或接口定义 (~物模型)相比较。

Thing Model and its relation to the Thing Description
7 物模型及其与物 描述的关系。

物 模型是对接口以及与属性动作事件进行 可能交互的逻辑描述, 然而它不包含 实例特定 信息,例如具体的协议用法(例如 IP 地址),甚至序列号和 GPS 位置。不过, 物模型允许包含例如安全方案, 如果它们适用于模型所描述的整个实例类别。 它们可能有 URL(例如 token 服务器), 这些 URL 可能需要省略或参数化(使用 模板),不过在许多情况下也可能给出。

物 模型可以用与物描述相同的基于 JSON 的格式序列化, 该格式也允许 JSON-LD 处理。 注意,由于缺少某些强制术语,物 模型不能像物 描述实例那样进行验证。 这意味着任何未使用占位符类型的术语, 仍然使用TD 信息 模型中声明的类型。例如, minimum 的值需要是 integer,除非使用了占位符。

可以使用该 JSON Schema来验证序列化为 JSON 的 TM 实例。

10.2 物模型声明

物 模型通过顶层 @type 被识别。 物模型定义 MUST 在顶层使用关键字 @type,其值为字符串类型,或 数组类型,且分别等于或包含 tm:ThingModel 此外, 为了将其识别为 JSON-LD 文档,物模型定义 MUST 在顶层使用关键字 @context,规则与物描述相同。 前缀 tm物描述的 上下文中定义,并指向物模型命名空间,如 4. 命名空间中所定义。意图是 tm 上下文中的词汇表只在 物 模型定义中使用,并在生成 物描述时被 移除或替换(另见 10.4 物描述 实例的派生)。

一个物模型 MAY 不包含实例特定的协议 绑定和安全信息,例如端点 地址。 因此,物模型定义即使没有 formsbasesecurityDefinitionssecurity 等 JSON 成员,也 是有效的。物模型即使使用了这些 JSON 成员 (例如作为模板),也是有效的; 不过会省略嵌套的强制成员,例如 href

示例 3展示了一个有效的灯物模型样例, 其中没有任何协议和安全信息。

10.3 建模工具

物模型定义的上下文中, 引入了可用于 建模的特定特性。

10.3.1 版本管理

物模型 定义 随时间发生变化时,这一点 SHOULD 反映在 version 容器中。 基于字符串的 术语 model 用在 version 容器内,用于提供这类版本 信息,例如 [SEMVER]。以下 片段展示了在物模型实例中使用 model

示例 61:物 模型版本管理
{
    // ...
    "@type": "tm:ThingModel",
    "title": "Lamp Thing Model",
    "description": "Lamp Thing Description Model",
    "version" : {"model": "1.0.0"},
    // ...
}

由于 物模型的定义, 术语 instance MUSTversion 容器中省略。

物 模型被更新并具有新版本时,这可能 影响其他使用扩展和导入特性的物 模型(见 10.3.2 扩展和 导入一节)。在某些情况下,也有必要在文件名和/或 相应 URL 中反映新版本,以标识该版本。

10.3.2 扩展和导入

物 模型可以通过在 links 定义中声明的 tm:extends 机制来扩展现有物模型当一个物模型 扩展另一个物模型时,MUST 使用至少一个 links 条目,其中 "rel": "tm:extends" 指向要被扩展的物模型物 模型将继承被扩展 物 模型的所有定义。可以通过从现有 TD 信息模型 (5. TD 信息 模型)提供更多 JSON 名称-值对,或使用上下文扩展概念(7. TD 上下文扩展), 用更多元数据扩展现有定义。物模型也可以 覆盖现有定义,例如 title(s)maximum 等。 对此存在两个限制:一个 物 模型 SHOULD NOT 覆盖被扩展物模型propertiesactions 和/或 events 映射中定义的 JSON 名称。 定义 SHOULD NOT 以使可能的实例值相对于原始 被扩展定义不再有效的方式被覆盖。 这些断言保留了 被扩展物模型中的语义。例如, 不允许将来自被扩展物 模型"minimum":2 覆盖为 "minimum":0。 同时,覆盖为 "minimum":5 是可行的, 因为所有实例值始终会满足被扩展 物模型的限制(更多说明另见 图 8)。

假设我们有如下示例中提供的基本模型描述:

示例 62:基本 On/Off 物模型定义
{
    "@context": ["https://www.w3.org/ns/wot-next/td"],
    "@type": "tm:ThingModel",
    "title": "Basic On/Off Thing Model",
    "properties": {
        "onOff": {
            "type": "boolean"
        }
    }
}

现在,设计一个名为 'Smart Lamp Control' 的新设备类模型, 它将用作创建 TD 实例的模板。 该模型将复用 'Basic On/Off Thing Model' 的现有定义,并用 dim 属性对其进行扩展:

示例 63:Smart Lamp Control 物模型定义
{
    "@context": ["https://www.w3.org/ns/wot-next/td"],
    "@type": "tm:ThingModel",
    "title": "Smart Lamp Control with Dimming",
    "links" : [{
        "rel": "tm:extends",
        "href": "http://example.com/BasicOnOffTM",
        "type": "application/tm+json"
     }],
    "properties" : {
        "dim" : {
            "title": "Dimming level",
            "type": "integer",
            "minimum": 0,
            "maximum": 100
        }
   }
}

请注意,title 被覆盖, 并将在创建 TD 实例时使用(另见下一小节 10.4 物描述 实例的派生)。

tm:extends 特性只允许继承 一个物模型的所有定义。然而,在许多 用例中,只希望导入一个或多个现有 物模型定义的片段。 为了 导入一个或多个现有物 模型定义的片段,引入了 tm:ref 术语, 它提供了应该被复用的现有(子)定义的位置。 tm:refMUST 遵循以作为 URI [RFC3986](第 4.1 节)的文件位置开始,随后是 # 字符,再随后是 JSON Pointer [RFC6901] 定义的模式。 注意,该 URI 也可以为空, 表示同文档引用 [RFC3986](第 4.4 节)。在这种情况下,tm:ref 应被解释为 相对引用。每次使用 tm:ref 时,所引用的预定义 及其依赖项(例如通过上下文扩展) MUST 被假定为在新定义的 定义处存在。

tm:ref 值的一部分 可能包含非 ASCII 字符,使用前需要进行 URL (“百分号”)编码。在对 tm:ref 值应用转义之前,实现应 检查该值是否尚未被编码。

以下示例展示了一个新的 TM 定义, 它将示例 62中属性 onOff 的现有定义导入到新的属性定义 switch 中。

示例 64:Smart Lamp Control 导入现有定义
{
    "@context": ["https://www.w3.org/ns/wot-next/td"],
    "@type": "tm:ThingModel",
    "title": "Smart Lamp Control",
    "properties" : {
        "switch" : {
            "tm:ref": "http://example.com/BasicOnOffTM.tm.jsonld#/properties/onOff"
        }
   }
}

作为使用 tm:ref 的相对导入示例, 以下物模型复用并增强(见下文)一个 genericTemperature 属性,将其用于两个更具体的属性中,分别描述 内部和外部温度值。

示例 65:Multi Sensor 物模型使用相对 导入复用定义
{
    "@context": "https://www.w3.org/ns/wot-next/td",
    "@type": "tm:ThingModel",
    "title": "Multi Sensor",
    "properties": {
        "genericTemperature": {
            "type": "number",
            "unit": "C"
        },
        "innerTemperature": {
            "tm:ref": "#/properties/genericTemperature",
            "title": "The inner temperature",
            "minimum": 10
        },
        "outerTemperature": {
            "tm:ref": "#/properties/genericTemperature",
            "title": "The outer temperature",
            "description": "The outer temperature is measured in Kelvin",
            "unit": "K"
        }
    },
    "tm:optional": [
        "/properties/genericTemperature"
    ]
}

在定义 "tm:ref" 的位置,可以添加附加 名称-值对。也允许覆盖来自被引用定义的名称-值对。 如果意图是 覆盖来自 tm:ref 的现有 JSON 名称-值对定义, 则 MUST 在提供新 值的 tm:ref 声明的同一层级使用相同的 JSON 名称。 覆盖 过程 MUST 遵循 [RFC7396] 中定义的 JSON Merge Patch 算法,其中被引用定义的内容会 使用新提供的 JSON 名称-值对进行修补。

注意,这些值也可以基于 JSON objectarray,或只是一个 null 值。null 会导致 目标中现有的 JSON 名称-值对被移除。

tm:extends 类似,为了保持语义含义, 定义 SHOULD NOT 以使可能的实例值 相对于原始被引用定义不再有效的方式被覆盖。

以下示例展示了一个新的 TM 定义, 它覆盖(maximum)、增强 (unit)并移除(title) 来自示例 63的现有定义。

示例 66:Smart Lamp Control 扩展并覆盖现有 定义
{
    "@context": ["https://www.w3.org/ns/wot-next/td"],
    "@type": "tm:ThingModel",
    "title": "Smart Lamp Control",
    "properties" : {
        "dimming" : {
            "tm:ref": "http://example.com/SmartLampControlwithDimming.tm.jsonld#/properties/dim",
            "title": null,
            "maximum": 80,
            "unit": "%"
        }
   }
}

基于 JSON Merge Patch 算法, {"title": null,"maximum": 80,"unit": "%"} 将作为被引用原始内容 {"title": "Dimming level", "type": "integer", "minimum": 0, "maximum": 100} 的补丁。

tm:extends 和基于 tm:ref 的导入机制也可以在同一个 TM 定义中同时使用。以下示例扩展了 示例 62中的 TM,并分别从 示例 3示例 63导入 statusdim 定义。

示例 67:带扩展和导入 机制的 Smart Lamp Control 物模型
{
    "@context": ["https://www.w3.org/ns/wot-next/td"],
    "@type": "tm:ThingModel",
    "title": "Smart Lamp Control",
    "links" : [{
        "rel": "extends",
        "href": "http://example.com/BasicOnOffTM",
        "type": "application/tm+json"
     }],
    "properties" : {
        "status" : {
            "tm:ref": "http://example.com/LampTM.tm.jsonld#/properties/status"
        },
        "dimming" : {
            "tm:ref": "http://example.com/LampWithDimmingTM.tm.jsonld#/properties/dim"
        }
   }
}

tm:extends 和基于 tm:ref 的导入机制显式支持传递 扩展(扩展层次结构)。例如, 假设有 3 个 TM:"A" 定义了对 TM "B" 的 tm:extends,而 "B" 自身定义了 对 TM "C" 的 tm:extends。因此, "A" TM 扩展了 "B" 和 "C" 的所有定义。 导致 无限循环的递归扩展 MUST NOT 被 定义。

下图总结了本节中介绍的扩展和导入 TM 功能允许的覆盖行为。三个物模型使用 tm:reftm:extends 特性来 复用 Smart Lamp Control 物模型的 TM 定义。第一个 物 模型dimmer 属性中导入并将 maximum 值覆盖为 120。然而,这会导致可能的实例值 (运行时)不在 Smart Lamp Control 物模型的原始 dim 定义中 0100 的范围内。因此,这样的物模型定义 不被允许。第二个模型将属性 type 值覆盖为 number。同样,这可能 导致数值型 dim 值不被 Smart Lamp Control 物 模型中原始 dim 类型定义(integer)接受。 最后一个模型以正确方式定义。 dim 的新范围所产生的可能实例值 也会满足原始 dim 定义。

Overwriting behavior
8 物模型的覆盖 行为。

10.3.3 组合

在某些应用中,复用现有 物 模型定义并将它们组合到新的 IoT 系统中是有益的。一个例子是设计一个新的 Smart Ventilator, 由两个子/子级物模型定义组成, 例如一个 Ventilation 物模型,它提供 on/offadjustRpm 能力;以及一个 LED 物模型,它提供 dimmableRGB 能力。

这种组合可以通过使用 links 容器来引入。如果希望 提供一个物模型由 一个或多个(子)物模型组成的信息,则 links 条目 MUST 使用指向这些(子)物 模型"rel": "tm:submodel" 可选地, MAY 提供一个 instanceName,以便为组合的 (子)物 模型关联单独名称。 当组合多个类似的 物 模型定义并需要区分它们时,这很有用。

可以遵循不同策略,从组合的 物描述物模型定义生成。 默认建议是从每个父级 和子/子级物模型生成一个 对应的物描述 (另见 10.4 物 描述实例的派生)。组合关系可以通过 collectionitem 关系类型反映在 物描述的 links 容器中。 这里给出一个基于 Smart Ventilation 的示例:

也可以生成单个 TD,其中包含顶层/父级 物模型的交互定义,以及所有 子/子级物模型的全部交互定义。 因此,生成过程 MUST 避免可能的名称 冲突。 以下示例展示了从 Smart Ventilator 物模型潜在生成的(自包含) 物描述

示例 70: Smart Ventilator TM 的自包含 TD
{
    "@context": "https://www.w3.org/ns/wot-next/td",
    "title": "Smart Ventilator",
    "securityDefinitions": {
        "basic_sc": {
            "scheme": "basic",
            "in": "header"
        }
    },
    "security": "basic_sc",
    "links": [
        {
            "rel": "type",
            "href": "./SmartVentilator.tm.jsonld",
            "type": "application/tm+json"
        }
    ],
    "properties": {
        "status": {
            "type": "string",
            "enum": [
                "on_value",
                "off_value",
                "error_value"
            ],
            "forms": [
                {
                    "href": "http://127.0.13.232:4563/status"
                }
            ]
        },
        "switch": {
            "type": "boolean",
            "description": "True=On; False=Off",
            "forms": [
                {
                    "href": "http://127.0.13.212:4563/switch"
                }
            ]
        },
        "adjustRpm": {
            "type": "number",
            "minimum": 200,
            "maximum": 1200,
            "forms": [
                {
                    "href": "http://127.0.13.212:4563/adjustRpm"
                }
            ]
        },
        "R": {
            "type": "number",
            "description": "Red color",
            "forms": [
                {
                    "href": "http://127.0.13.211:4563/R"
                }
            ]
        },
        "G": {
            "type": "number",
            "description": "Green color",
            "forms": [
                {
                    "href": "http://127.0.13.211:4563/G"
                }
            ]
        },
        "B": {
            "type": "number",
            "description": "Blue color",
            "forms": [
                {
                    "href": "http://127.0.13.211:4563/B"
                }
            ]
        }
    },
    "actions": {
        "fadeIn": {
            "title": "fadeIn",
            "input": {
                "type": "number",
                "description": "fadeIn in ms"
            },
            "forms": [
                {
                    "href": "http://127.0.13.211:4563/fadeIn"
                }
            ]
        },
        "fadeOut": {
            "title": "fadeOut",
            "input": {
                "type": "number",
                "description": "fadeOut in ms"
            },
            "forms": [
                {
                    "href": "http://127.0.13.211:4563/fadeOut"
                }
            ]
        }
    }
}

10.3.4 tm:optional

在某些情况下,希望不强制哪些交互 可供性是强制性的,并且不一定需要在 物描述 实例中实现。如果交互模型不是 物描述 实例中必须实现的内容, 物 模型定义 MUST 使用 JSON 成员名称 tm:optional tm:optional MUST 是顶层的 JSON 数组。 tm:optional 的值 MUST 提供 JSON Pointer [RFC6901] 对所需交互模型定义的引用。 tm:optional 的 JSON Pointers MUST 解析为整个交互可供性映射定义。

以下样例展示了对事件交互 overheating 使用 tm:optional

示例 71: 带有用于交互 可供性的 tm:optional 术语的物模型。
{
    "@context": ["https://www.w3.org/ns/wot-next/td"],
    "@type": "tm:ThingModel",
    "title": "Lamp Thing Model",
    "description": "Lamp Thing Model Description",
    "tm:optional": [
        "/events/overheating"
    ],
    "properties": {
        "status": {
            "description": "current status of the lamp (on|off)",
            "type": "string",
            "readOnly": true
        }
    },
    "actions": {
        "toggle": {
            "description": "Turn the lamp on or off"
        }
    },
    "events": {
        "overheating": {
            "description": "Lamp reaches a critical temperature (overheating)",
            "data": {"type": "string"}
        }
    }
}

由于事件 overheating 不是强制的,因此它可以不在 物描述 实例中可用。

请注意,如果一个物模型定义中的可选定义 通过使用 tm:ref 被另一个 物 模型扩展,则它可以被覆盖:

示例 72: 物模型覆盖前一个 物模型示例的 tm:optional。
{
    "@context": ["https://www.w3.org/ns/wot-next/td"],
    "@type": "tm:ThingModel",
    "title": "Lamp Thing Model (All Mandatory)",
    "description": "Lamp Thing Model description expects all interaction affordances (status, toggle, and overheating)",
    "links": [
       {
          "rel": "tm:extends",
          "href": "./lampThingModel.tm.jsonld",
          "type": "application/tm+json"
       }
    ],
    "events": {
        "overheating": {
            "tm:ref": "./lampThingModel.tm.jsonld#/events/overheating"
        }
    }
}

10.3.5 占位符

物 模型可以指定 TD 实例中应使用哪些术语,但它们的值并不具体, 要到 TD 实例化期间才首次知道。在已预先知道 TD 实例术语但不知道其值的情况下, 可以在物模型中 MAY 使用占位符标记。 当从物模型创建 TD 实例时,占位符标记 MUST 被替换为 具体值(例如 JSON number、JSON string、JSON object 等)。 基于字符串的 占位符模式 MUST 遵循基于正则表达式 {{2}[ -~]+}{2} 的有效模式(例如 {{PLACEHOLDER_IDENTIFIER}})。 {{}} 之间的字符 用作占位符的标识符名称。 该标识符名称可用于在替换过程中识别占位符。 占位符 MUST 应用于 JSON 名称-值对的值中。 如果 JSON 名称-值对的非 字符串值具有占位符,则该值 MUST (临时)被类型化为字符串。 在替换占位符之后, 例如创建物描述实例时, 原始类型会与相应替换后的值一起应用。

以下物模型示例定义了不同的 占位符。占位符映射用于应用 替换并转换预期值类型。

10.4 物描述 实例的派生

物 模型可以用作模板,以根据 5. TD 信息 模型6. TD 表示 格式两节中定义的限制生成物 描述。在此过程中,必须补充缺失的数据,例如 通信和安全元数据,以创建有效的物描述 实例。一个物模型 MUST 以 不会产生不一致的方式定义,否则会导致物 描述无法满足 5. TD 信息 模型6. TD 表示 格式中所描述的要求。 用于从物模型 派生物 描述实例的 TM-to-TD 生成器,会使用以下步骤将其转换为 部分 TD

最后,TM-to-TD 生成器会取得生成的 部分 TD,并 通过最后一步将其转换为物描述

建议物 模型id 值提供一个占位符,例如 "id": "urn:example:{{RANDOM_ID_PATTERN}}", 以用于 TD 生成过程。请避免在 id 模式中包含元数据。

遵循物模型物描述 实例可以携带关于其派生自哪种类型 物模型的信息。 在此上下文中,可以使用带 "rel": "type" 的链接概念 (另见 5.3.4.1 Link 一节),如下例所示:

请注意,一个 TD 一次只能是一个 TM 的实例。 这意味着对于物描述: links 数组中带有 "rel": "type" 的条目最多 MUST 使用 一次。 如果希望在物描述中反映与其他物的所有关系, 可以考虑 TM 中的组合机制(见 10.3.3 组合一节)。

10.5 示例

以下物模型扩展了 示例 63所示模型,并覆盖 dim 属性的 maximum

示例 75: 使用修改后的 dim 约束扩展 Smart Control Lamp
{
    "@context": ["https://www.w3.org/ns/wot-next/td"],
    "@type": "tm:ThingModel",
    "links" : [{
        "rel": "tm:extends",
        "href": "http://example.com/SmartControlLampTM",
        "type": "application/tm+json"
     }],
    "properties" : {
        "dim" : {
            "maximum": 200
        }
   }
}

从该物模型派生出的预期 物描述将是(应用 HTTP 绑定和 basic 安全之后):

示例 76:物 描述
{
    "@context": ["https://www.w3.org/ns/wot-next/td"],
    "@type": "Thing",
    "title": "Smart Lamp Control",
    "securityDefinitions": {
        "basic_sc": {"scheme": "basic", "in": "header"}
    },
    "security": "basic_sc",
    "links" : [{
        "rel": "type",
        "href": "url/to/SmartLampControlModifiedDimTM",
        "type": "application/tm+json"
     }
   ],
   "properties" : {
        "onOff": {
            "type": "boolean",
            "forms": [{"href": "https://smartlamp.example.com/onoff"}]
        },
        "dim" : {
            "type": "integer",
            "minimum": 0,
            "maximum": 200,
            "forms": [{"href": "https://smartlamp.example.com/dim"}]
        }
   }
}

11. 安全考量

一般而言,用于保护 WoT 系统的安全措施将取决于该系统可能 面临的威胁和攻击者,以及需要保护的资产价值。 关于 Web of Things 的安全(和隐私)考量的详细讨论, 包括可适配各种情形的威胁模型,见资料性文档 [WOT-SECURITY-GUIDELINES]。 许多 WoT 物与 Web 服务相似,并使用相同技术。 除了下面的特定安全考量之外,还应评估 Web 服务指南中讨论的安全风险和缓解措施,例如 OWASP Top 10 [OWASP-Top-10], 并在适用时加以处理。本节仅讨论与 WoT 物描述直接 相关的安全风险和可能的缓解措施。

WoT 物描述既可以描述安全的网络接口,也可以描述 不安全的网络接口。当物描述被改配到现有网络接口上时, 不应期望该网络接口的安全状态发生变化。

使用 WoT 物描述会引入以下各节中给出的安全 风险。每个风险之后,我们都会建议一些可能的缓解措施。

11.1 TD 拦截和 篡改

拦截和篡改 TD 可用于发起中间人攻击, 例如通过重写 TD 中的 URL,将访问重定向到能够 捕获或操纵数据的恶意中介。

缓解措施:
物描述 SHOULD 只通过 相互认证的安全信道获取。 相互认证 确保消费者和 TD 提供者都确信通信中另一方的身份。 不过,相互认证也可用于识别消费者, 这在某些情况下可能并不理想(隐私风险)。 在 消费者与人相关联的情况下, 例如浏览器,TD MAY 通过仅认证 TD 提供者的信道获取。

11.2 上下文拦截和 篡改

拦截和篡改上下文定义文件 可通过修改词汇表解释来促成攻击。上下文扩展(见 7. TD 上下文扩展) 如果从 Web 上通过非安全连接加载,例如 HTTP, 就存在被攻击者更改的风险,并可能以危及安全的方式 修改TD 信息模型

12.1 上下文获取中所建议, 在受约束的实现上,上下文定义文件 应预先安装,并使用安全的软件更新过程进行管理, 上下文 URL 仅用于标识已知上下文,而不用于获取它们。 因此,本考量仅在动态获取上下文定义文件 在其他方面不可避免时适用,例如在支持通用语义处理的 目录服务中。

缓解措施:
理想情况下,上下文定义文件应仅通过 相互认证建立的安全信道获取;但值得注意(也令人遗憾)的是, 许多上下文使用“plain” HTTP URL 指示。 不过,如果未先使用 TLS 建立安全传输信道, HTTP 协议容易受到拦截和修改。如果有必要 获取上下文定义文件,实现即使只给出了 HTTP URL,也应首先尝试使用基于 TLS 的 HTTP。

11.3 有限时长访问

在某些场景中,可能希望限制某些用户对一组物的访问范围 和持续时间。例如,如果 A 正在拜访 B 的家,B 可能希望 向 A 提供对车库门开启器和汽车充电器的临时且受限访问, 以便 A 可以使用它们。不过,范围可以受到限制, 使 A 无法访问这些物的某些管理功能 (例如,更改车库门可以保持开启的时长,或更改充电 速率)。此外,该访问应在预计 A 已离开之后过期, 例如一周之后。

缓解措施:
为了限制对物的访问范围和持续时间, SHOULD 使用 token 来管理访问。 注意,这包括 OAuth2 等机制,它们提供 token 生成流程,其中用户认证和授权的验证由单独的 token 提供者服务处理。Token 提供者服务(如果适当或出于隐私考虑而希望, 可以由物的管理员直接管理)可以提供有限时长的 token,并使用 scope 限制访问。Scope 可以 限制对特定交互的访问,但不足以限制持续时间。 见 [RFC9200]。

11.4 漏洞审计

能够访问一组 TD 的攻击者,例如访问 WoT Discovery 返回的 TD, 可能能够使用这些信息识别易受攻击的设备,并计划对其发动攻击。

缓解措施:
IoT 系统部署者可以使用相同的信息 来审计其 IoT 系统,并确保易受攻击的系统得到充分保护 (如有必要,通过传输安全和/或分段网络等外部 手段),或得到加固。也可以不通过发现提供 已知易受攻击系统的 TD。然而,这并不是推荐做法, 因为依靠隐蔽实现安全是一种糟糕的防御: 即使 TD 的分发受限,攻击者仍可通过其他手段 发现该系统。不过,“vulnerable”的定义取决于 信息可用的上下文以及信息可提供给谁。理想情况下, 只有有权访问 TD 所描述物的人才应获得这些 TD。 如果漏洞扫描 是一个顾虑,则 auto 安全方案 MAY 被使用。

11.5 脚本注入

TD 中给出的许多字符串,尤其是 title/titlesdescription/descriptions 中携带的值, 意图是人类可读的。应用可以取得这些字符串 并用它们生成用户界面,例如列出一组可用物及其标题 和描述的 Web 仪表板。如果此类界面是通过字符串替换 天真地生成的,例如将这些字符串的值插入 HTML 模板中 标记的位置以创建最终 HTML,则原始字符串中的任何 HTML 标记都会在显示仪表板的浏览器上下文中被解释。 攻击者可能以各种方式在 HTML 中嵌入脚本,并使这些脚本 在用户交互时甚至自动执行(例如,在页面加载时或发生错误时, 后者可以被有意触发)。由于该字符串将由 TD 生产者生成,而仪表板将由不同来源生成, 这是一种跨站脚本(XSS)攻击形式。

缓解措施:
在生成 HTML 时,来自 TD 的字符串应像任何其他 外部字符串来源一样被谨慎处理。作为策略,强烈建议 来自 TD 的字符串要么使用经过仔细审查的 HTML sanitizer 进行清理,以禁用任何标记;要么使用 DOM 节点操作 API 插入到 HTML 模板中,以转义任何标记。 也可能使用来自 TD 的字符串生成其他标记语言中的文档, 例如 MD 文件或 XML。此类用法应采取等效 预防措施,确保字符串值在插入模板之前得到清理。 不幸的是,这种清理也会禁用为国际化目的而包含的 任何 HTML 标记,例如用于设置双向文本中文本渲染的 初始方向。 HTML 标记 SHOULD NOT 在 TD 字符串中用于国际化 目的。

11.6 JSON 解析

RFC 8259, 第 12 节:JSON 不应使用 eval() 作为 JavaScript 进行解析。WoT 物描述旨在 成为用于元数据的纯数据交换格式,而不是用于保存 可执行内容。不过,一个(无效的)TD 可能包含 JavaScript 代码,该代码在执行时可能产生危及系统安全的副作用。

缓解措施:
WoT 物描述 JSON-LD 序列化 MUST NOT 被传递 给代码执行机制(例如 JavaScript 的 eval() 函数)进行解析。
:其他 注入风险

[WOT-DISCOVERY] 中讨论了其他代码注入风险。 TD 中的其他字符串,例如为 titledescription 给出的值, 在用于 SQL、HTML 或其他可执行上下文的模板之前, 应进行清理。不过,本风险专门讨论解析 JSON 时的 Javascript 注入风险。

11.7 JSON-LD 扩展

JSON-LD 处理通常包括将短术语替换为更长的 IRI [RFC3987]。 因此,WoT 物描述在使用 JSON-LD 1.1 处理器处理时 可能会显著扩展,并且在最坏情况下,生成的数据可能消耗 接收方的全部资源,或导致可被利用的缓冲区溢出。

缓解措施:
消费者 SHOULD 设置并强制执行内存 使用限制,以防止 JSON-LD 处理期间发生缓冲区溢出和资源耗尽。

12. 隐私考量

隐私风险将取决于物与可识别人员的关联, 以及可从这种关联获得的直接信息和推断信息。 关于 Web of Things 的隐私(和安全)考量的详细讨论, 包括可适配各种情形的威胁模型,见资料性文档 [WOT-SECURITY-GUIDELINES]。 本节仅讨论与 WoT 物描述直接相关的隐私风险和可能的 缓解措施。

使用 WoT 物描述会引入以下各节中给出的隐私 风险。每个风险之后,我们都会建议一些可能的缓解措施。

12.1 上下文获取

WoT 物描述可以使用 JSON-LD 1.1 处理器 [json-ld11] 进行求值,该处理器通常会 自动跟随指向远程上下文的链接(即 TD 上下文扩展,见 7. TD 上下文扩展), 从而在消费者未对每一个文件显式请求的情况下 传输文件。如果远程上下文由第三方提供, 这可能允许它们收集使用模式或类似信息,从而导致 私有信息的泄露,或泄露可用于推断私有信息的信息。 在 WoT 的情况下,攻击者还可以观察此类获取产生的网络流量, 并使用获取的元数据(例如目标 IP 地址)推断有关设备的信息, 尤其是在使用特定领域词汇表时。即使连接被加密, 这也是一种风险,并且与 DNS 隐私泄露有关。 另见 11.2 上下文拦截 和篡改,这是一种相关的安全风险,也可以通过以下 缓解措施避免。

缓解措施:
资源受约束设备上的实现预计会执行原始 JSON 处理 (而不是 JSON-LD 处理),并仅支持有限集合的 特定领域扩展。支持的扩展集合可以由 WoT Profile [WOT-PROFILES] 建立,例如。受约束实现 SHOULD 使用经过审查的 受支持上下文扩展版本,这些版本以静态方式或作为 安全更新过程的一部分进行管理。 受约束实现 SHOULD NOT 跟随指向远程 上下文的链接。 在这种情况下,URL 仅用于 标识扩展,而不用于获取其定义。

12.2 不可变标识符

包含标识符(id)的物描述 可能描述一个与可识别人员相关联的物。这类标识符 会带来各种风险,包括跟踪。不过,如果该标识符也是 不可变的,则跟踪风险会被放大,因为设备可能被出售或赠予 另一个人,而已知 ID 可用于跟踪该人。

缓解措施:

TD 中使用的所有标识符 SHOULD 都是可变的,并且尤其 SHOULD 有一种机制在必要时更新 id 具体而言,id 不应固定在硬件中。不过,这确实 与 Linked Data 的理想相冲突,即标识符是固定的 URI。 然而,作为策略,强烈建议部署在配置发生重大变化或 重新初始化时更新标识符。配置重大变化的示例包括 将物移动到新的局域网、分配新的域名,或 将物从一个 hub 注销并注册到新的 hub。 通常,表明所有权可能发生变化的配置变化 应导致创建新的标识符。如果希望在设备的运行阶段 进行更频繁的更改,可以放置一种机制,以便在作出更改时 仅通知授权用户标识符的变化。不过请注意,某些类别的 设备,例如医疗设备,在某些司法管辖区可能依法要求 不可变 ID。理想情况下,任何必需的不可变标识符 都应仅通过可供性提供,例如通过一个属性,其值只有在 适当认证和授权之后才能获得,并与 TD 标识符分开管理。 如果有必要将不可变标识符用作 TD 标识符,则应特别注意 保护包含此类不可变标识符的文件(例如物描述)的访问安全。

12.3 指纹识别

如上所述,TD 中的 id 成员可能 带来隐私风险。不过,即使按所述更新 id 以缓解其 跟踪风险,仍可能通过指纹识别将 TD 与特定物理设备 关联起来,并由此关联到可识别人员。

即使无法通过指纹识别识别特定设备实例, 也可能从 TD 中的信息推断设备类型,例如交互集合, 并使用这种类型推断关于可识别人员的私有信息, 例如医疗状况。

缓解措施:
只有授权用户 SHOULD 被提供对 的物描述的访问。 TD 中 SHOULD 仅提供授权级别和 用例所需的信息量。 如果 TD 仅通过安全且保密的信道 分发给授权用户,例如通过要求认证的目录服务, 则外部未授权方将无法访问 TD 来对其进行指纹识别。 为进一步缓解此风险,对于 TD 的特定用例不必要的信息 应尽可能省略。例如,对于不保存关于物状态的消费者 与设备进行 ad-hoc 连接时,可以省略 id。 如果消费者在其用例中不需要某些交互,则可以省略它们。 如果消费者无权使用某些交互,它们也可以同样被省略。

12.4 ID 元数据

TD 的 id 字段值可能变得可供 无法访问完整 TD 的实体使用。如果 id 的值包含 嵌入式元数据,例如设备类型或所有者,则这可能被用于推断 个人信息。

缓解措施:
TD 的 idSHOULD NOT 包含 描述物或来自 TD 本身的元数据。 为管理 TD 而生成的任何临时 ID,例如数据库或目录服务的 ID, SHOULD NOT 包含描述物或来自 TD 本身的元数据。12.5 全局 唯一标识符中的建议使用随机 UUID 也能缓解此风险。

12.5 全局唯一 标识符

如果需要集中式权威来创建和分发全局唯一标识符, 则它们会带来隐私风险,因为第三方会知道这些 标识符。

缓解措施:
TD 中的 id 字段有意不要求 全局唯一。有多种加密机制(例如随机 UUID)可用于 以分布式方式生成合适的 ID,而不需要中央注册表。 这些机制通常生成重复标识符的概率很低, 并且系统设计需要考虑这一点;例如,通过检测重复 并在必要时重新生成 ID。ID 的范围也不需要是全局的: 使用只在某个上下文中区分物的标识符是可接受的, 例如在家中或工厂内。TD 标识符 SHOULD 使用分布式 机制(例如 UUID)生成,该机制提供高概率的 唯一性。 TD 标识符 SHOULD NOT 使用集中式 权威生成。

12.6 个人可识别信息的 推断

在许多地区,为了保护用户隐私, 对个人可识别信息的处理有法律要求, 即可与特定个人相关联的信息。当然, 这类信息可以由 IoT 设备直接生成。然而, IoT 设备的存在和元数据(物描述中存储的数据类型) 也可能包含或被用于推断个人可识别信息。 这些信息可以简单到某人拥有某种类型设备这一事实, 而这可能导致关于该人的附加推断。

缓解措施:
作为策略,强烈建议将与个人设备关联的 物描述视为包含个人可识别信息,即使这些信息并不显式。 作为该原则的一个应用示例,请考虑如何获得用户同意。 使用生成的个人可识别数据的同意, 通常是在与 消费数据的系统配对时获得的,而这也经常是 物描述被注册到本地目录,或使用物描述来访问设备的系统 进行消费的时候。在这种情况下,使用来自 的数据的同意,可以与 访问该的物描述的同意结合起来。 作为第二个示例,如果我们认为 TD 包含个人可识别信息, 则不应无限期保留它,也不应将其用于同意所授予目的之外的 其他目的。

13. IANA 考量

13.1 application/td+json 媒体类型 注册

类型名称:
application
子类型名称:
td+json
必需参数:
可选参数:
编码考量:
RFC 6839,第 3.1 节
安全考量:
见已发布规范中的 11.2 上下文 拦截和篡改11.6 JSON 解析11.7 JSON-LD 扩展,以及 12.1 上下文 获取
互操作性考量:
RFC 8259

处理一致性内容和非一致性内容的规则 在本规范中定义。

已发布规范:
W3C Web of Things (WoT) Thing Description 1.1: https://www.w3.org/TR/wot-thing-description11/
使用此媒体类型的应用:
W3C Web of Things 中的所有参与实体, 即 消费者和 中介,如 W3C Web of Things (WoT) Architecture 1.1: https://www.w3.org/TR/wot-architecture11/ 文档中所定义。
片段标识符考量:
RFC 6839,第 3.1 节
附加信息:
魔数:
不适用
文件扩展名:
.jsontd
: 其他扩展名

请查看当前 IANA 注册;将来 .td.json 和 .td.jsonld 也可能被允许。

Macintosh 文件类型代码:
TEXT
进一步信息的联系人及电子邮件地址:
Matthias Kovatsch <w3c@kovatsch.net>
预期用途:
COMMON
使用限制:
作者:
Web of Things (WoT) Thing Description 规范 是 Web of Things Working Group 的产物。
变更控制者:
W3C

13.2 application/tm+json 媒体类型 注册

类型名称:
application
子类型名称:
tm+json
必需参数:
可选参数:
编码考量:
RFC 6839,第 3.1 节
安全考量:
见已发布规范中的 11.2 上下文 拦截和篡改11.6 JSON 解析11.7 JSON-LD 扩展,以及 12.1 上下文 获取
互操作性考量:
RFC 8259

处理一致性内容和非一致性内容的规则 在本规范中定义。

已发布规范:
W3C Web of Things (WoT) Thing Description 1.1
使用此媒体类型的应用:
W3C Web of Things 中的所有参与实体, 即 消费者和 中介,如 W3C Web of Things (WoT) Architecture 1.1 文档中所定义。
片段标识符考量:
见 RFC 6901,第 3 节第 6 节。注意,保留字符可以进行百分号 编码。
附加信息:
魔数:
不适用
文件扩展名:
.jsontm、.tm.json、.tm.jsonld(首选文件 扩展名)
Macintosh 文件类型代码:
TEXT
进一步信息的联系人及电子邮件地址:
Sebastian.Kaebisch@siemens.com
预期用途:
COMMON
使用限制:
作者:
Web of Things (WoT) Thing Description 规范 是 Web of Things Working Group 的产物。
变更控制者:
W3C

13.3 CoAP Content-Format 注册

IANA 在 Constrained RESTful Environments (CoRE) Parameters 注册表内的 CoAP Content-Formats 子注册表中为媒体 类型分配紧凑的 CoAP Content-Format ID [RFC7252]。 WoT Thing Description 的 Content-Format ID 是 432, WoT Thing Model 的 Content-Format ID 是 -(待定)。

13.3.1 WoT Thing Description

媒体类型:
application/td+json
编码:
-
ID:
432
参考:
["Web of Things (WoT) Thing Description 1.1", April 2022]

13.3.2 WoT Thing Model

媒体类型:
application/tm+json
编码:
-
ID:
433
参考:
["Web of Things (WoT) Thing Description 1.1", April 2022]

A. 带协议绑定的物描述 实例示例

本节是非规范性的。

以下 TD 示例使用 HTTP、CoAP 和 MQTT 协议 绑定。这些 TD 具有上下文扩展,其假定 存在类似于 [HTTP-in-RDF10] 的 CoAP-in-RDF 和 MQTT-in-RDF 词汇表, 它们可分别通过命名空间 http://www.example.org/coap-binding#http://www.example.org/mqtt-binding# 访问。请注意,位于 "https://www.w3.org/2022/wot/td/v1.1" 的 TD 上下文已经 包含 [HTTP-in-RDF10],因此 HTTP 上下文扩展可以直接使用。请注意,每个 绑定规范 都包含最新的词汇表术语和示例。

我们在下面看到的上下文扩展对 TD 消费者具有以下 指示:

首先展示使用单一协议的 TD。然后,引入具有 多个协议的 TD,其中每个交互 可供性都有一个带有一种协议的 form。

A.1 使用 CoAP 协议绑定的 MyLampThing 示例

的特性列表:

A.2 使用 MQTT 协议绑定的 MyIlluminanceSensor 示例

的特性列表:

A.3 Webhook 事件示例

的特性列表:

除了向该物发送周期性 POST 请求之外, 消费者可以提供响应 数据,其中包含该物应何时提供下一个 POST 请求的信息。 这是通过使用 dataResponse 字段描述的。

A.4 带 HTTP、CoAP 和 MQTT 协议绑定的 Lamp Thing

的特性列表:

示例 80: 每个 Form 使用一种协议的 Lamp 多协议 TD
{
    "@context": [
        "https://www.w3.org/ns/wot-next/td",
        {
            "cov": "http://www.example.org/coap-binding#",
            "mqv": "http://www.example.org/mqtt-binding#",
            "htv": "http://www.w3.org/2011/http#"
        }
    ],
    "title": "LampThing",
    "id": "urn:dev:ops:32473-WoTLamp-1234",
    "securityDefinitions": {
        "nosec_sc": {
            "scheme": "nosec"
        }
    },
    "security": ["nosec_sc"],
    "properties": {
        "switchState": {
            "type": "boolean",
            "readOnly": true,
            "observable": false,
            "forms": [
                {
                    "href": "http://example.com/light/switchstate",
                    "op": "readproperty",
                    "contentType": "application/json",
                    "htv:methodName":"GET"
                }
            ]
        },
        "brightness": {
            "type": "number",
            "readOnly": true,
            "observable": false,
            "forms": [
                {
                    "href": "coap://example.com/light/brightness",
                    "op": "readproperty",
                    "contentType": "application/json",
                    "cov:method": "GET"
                }
            ]
        }
    },
    "actions": {
        "switchLight": {
            "input":  {
                "type": "boolean"
            },
            "forms": [
                {
                    "href": "http://example.com/switch/state",
                    "op": "invokeaction",
                    "contentType": "application/json",
                    "htv:methodName":"POST"
                }
            ]
        },
        "setBrightness": {
            "input":  {
                "type": "number",
                "maximum":255
            },
            "forms": [
                {
                    "href": "coap://example.com/light/brightness",
                    "op": "invokeaction",
                    "contentType": "application/json",
                    "cov:method": "POST"
                }
            ]
        }
    },
    "events":{
        "concentration": {
            "title": "Gas Concentration Event Stream",
            "data":{
                "type": "integer",
                "minimum": -1,
                "maximum": 65535
            },
            "forms": [
                {
                    "href": "mqtt://broker.com",
                    "contentType": "application/json",
                    "op": "subscribeevent",
                    "mqv:filter": "application/deviceid/sensor/concentration",
                    "mqv:controlPacket": "subscribe"
                }
            ]
        }
    }
}

A.5 混合使用 HTTP、CoAP 和 MQTT 协议绑定的 Lamp Thing

的特性列表:

示例 81: 每个 Form 使用多种协议的 Lamp 多协议 TD
{
    "@context": [
        "https://www.w3.org/ns/wot-next/td",
        {
            "cov": "http://www.example.org/coap-binding#",
            "mqv": "http://www.example.org/mqtt-binding#",
            "htv": "http://www.w3.org/2011/http#"
        }
    ],
    "title": "Lamp",
    "id": "urn:dev:ops:32473-WoTLamp-5678",
    "securityDefinitions": {
        "nosec_sc": {
            "scheme": "nosec"
        }
    },
    "security": ["nosec_sc"],
    "properties": {
        "switchState": {
            "type": "boolean",
            "readOnly": true,
            "observable": false,
            "forms": [
                {
                    "href": "http://example.com/light/switchstate",
                    "op": "readproperty",
                    "contentType": "application/json",
                    "htv:methodName":"GET"
                },
                {
                    "href": "coap://example.com/light/switchstate",
                    "op": "readproperty",
                    "contentType": "application/json",
                    "cov:method": "GET"
                }
            ]
        },
        "brightness": {
            "type": "number",
            "readOnly": true,
            "observable": true,
            "forms": [
                {
                    "href": "http://example.com/light/switchstate",
                    "op": "readproperty",
                    "contentType": "application/json",
                    "htv:methodName":"GET"
                },
                {
                    "href": "coap://example.com/light/switchstate",
                    "op": "readproperty",
                    "contentType": "application/json",
                    "cov:method": "GET"
                },
                {
                    "href": "mqtt://broker.com",
                    "mqv:filter": "application/deviceid/sensor/brightness",
                    "op": "observeproperty",
                    "mqv:controlPacket": "subscribe"
                }
            ]
        }
    },
    "actions": {
        "switchLight": {
            "input":  {
                "type": "boolean"
            },
            "forms": [
                {
                    "href": "http://example.com/switch/state",
                    "op": "invokeaction",
                    "contentType": "application/json",
                    "htv:methodName":"POST"
                }
            ]
        },
        "setBrightness": {
            "input":  {
                "type": "number",
                "maximum":255
            },
            "forms": [
                {
                    "href": "coap://example.com/light/brightness",
                    "op": "invokeaction",
                    "contentType": "application/json",
                    "cov:method": "POST"
                }
            ]
        }
    },
    "events":{
        "concentration": {
            "title": "Gas Concentration Event Stream",
            "data":{
                "type": "integer",
                "minimum": -1,
                "maximum": 65535
            },
            "forms": [
                {
                    "href": "mqtt://broker.com",
                    "contentType": "application/json",
                    "op": "subscribeevent",
                    "mqv:filter": "application/deviceid/sensor/concentration",
                    "mqv:controlPacket": "subscribe"
                },
                {
                    "cov:method": "GET",
                    "href": "coap://example.com/sensor/gasconcentration",
                    "contentType": "application/json",
                    "op": "subscribeevent",
                    "subprotocol": "cov:observe"
                }
            ]
        }
    }
}

B. 用于 TD 实例 验证的 JSON Schema

本节是非规范性的。

用于对以基于 JSON 的格式序列化的物描述 实例进行语法验证的 JSON Schema [JSON-SCHEMA] 文档可在 https://www.w3.org/ns/wot-next/td-schema 获得。 该 JSON Schema 不要求带有默认值的术语 必须出现。因此,带有默认值的术语是可选的。 (另见 5.4 默认值 定义

本文档定义的物描述 允许通过使用 JSON-LD [json-ld11] 中已知的 @context 机制添加外部词汇表, 并且这些外部词汇表中的术语可以与 5. TD 信息模型中定义的术语 一起使用。出于这个原因, 下面的 JSON schema 在这方面有意保持非严格。 如果不使用外部词汇表,则可以在不同 作用域/层级中将 additionalProperties schema 属性的值 true 替换为 false, 以执行更严格的验证。

C. 物描述中的 contentType 用法

本节是非规范性的。

请求和响应变化的不同情况在 5.3.4.2.2 响应相关 术语用法中说明。下面的表格以简洁方式总结这些情况。 表格从较简单的情况开始,例如 单个 contentType,然后进入较复杂的情况, 例如多个 contentType。在所有表格中, 消息都从物的视角来看,其中 input 表示从消费者发送到物的消息(例如,请求), output 表示从物发送到消费者的消息 (例如,响应)。

这些情况已编号,可用于将它们与表格后的 示例关联起来。

32 单一 contentType 情况, 其中 input 和 output 都使用相同的 contentType
情况 所需术语 说明 消费者行为 物行为
情况 1A:存在 input,不存在 output form 内的 contentType contentType 仅指 input
  • 根据 form 中可用的 contentType 对 input 负载进行编码。
  • 如果所用协议允许,则将 contentType 的值添加到 input header。
  • 如果所用协议允许,则使用 input header contentType 解码 input 负载。
  • 如果所用协议不允许或不可用,则使用 form 中可用的对应 contentType 解码 output 负载。
情况 1B:不存在 input,存在 output。 form 内的 contentType contentType 仅指 output。
  • 如果所用协议允许,则将对 form 中可用的 contentType 的偏好添加到 input header。
  • 如果所用协议允许,则使用 output header contentType 解码 output 负载。
  • 如果所用协议不允许或不可用,则使用 form 中可用的对应 contentType 解码 output 负载。
  • 使用 form 中可用的对应 contentType 对 output 负载进行编码。
  • 如果所用协议允许,则将 contentType 的值添加到 output header。
情况 1C:存在 input 和 output,消息使用相同 contentType form 内的 contentType contentType 同时指 input 和 output。
  • 根据 form 中可用的 contentType 对 input 负载进行编码。
  • 如果所用协议允许,则将 contentType 的值添加到 input header。
  • 如果所用协议允许,则使用 contentType 中的值,将对 output 负载的 contentType 的偏好 添加到 input header。
  • 如果所用协议允许,则使用 output header contentType 解码 output 负载。
  • 如果所用协议不允许或不可用,则使用 form 中可用的对应 contentType 解码 output 负载。
  • 如果所用协议允许,则使用 input header contentType 解码 input 负载。
  • 如果所用协议不允许或不可用,则使用 form 中可用的对应 contentType 解码 input 负载。
  • 使用 form 中可用的对应 contentType 对 output 负载进行编码。
  • 如果所用协议允许,则将 contentType 的值添加到 output header。

下表考虑了更多变化,这些变化与操作 input 可以接受不同 contentType,或 output 可以返回 不同 contentType 的情况相关。 可能存在一个交互可供性具有多个 forms 的情况。 具有多个 forms 的此类情况应被视为上表和下表中 情况的组合。

33 多个 contentType 情况,其中 input 和 output 可以使用不同的 contentTypes,并且可能存在 多个 forms
情况 所需术语 说明 消费者行为 物行为
情况 2A:存在单个 input 和单个 output, 消息使用不同的 contentType form 内的 contentTyperesponseresponse 具有 不同值的 contentType form 层级中的 contentType 指 input,而 response 中的 contentType(response 层级)指 output
  • 根据 form 层级中可用的 contentType 对 input 负载进行编码。
  • 如果所用协议允许,则将 form 层级 contentType 的值添加到 input header。
  • 如果所用协议允许,则使用 response 层级 contentType,将对 output 负载的 contentType 的偏好添加到 input header。
  • 如果所用协议允许,则使用 output header contentType 解码 output 负载。
  • 如果所用协议不允许或不可用,则使用 response 层级中可用的对应 contentType 解码 output 负载。
  • 如果所用协议允许,则使用 input header 解码 input 负载。
  • 如果所用协议不允许或不可用,则使用 form 层级中可用的对应 contentType 解码 input 负载。
  • 使用 response 层级中可用的对应 contentType 对 output 负载进行编码。
  • 如果所用协议允许,则将 response 层级 contentType 的值添加到 output header。
情况 2B:存在 input 和多个可能的 output, 消息使用相同的 contentType form 内的 contentTypeadditionalResponses。 可能需要 additionalResponses 数组项中的 schema form 层级中的 contentType 指 input 和普通 output。 additionalResponses 不需要 contentType,因为默认值规则 适用。这与存在实际单个 contentType 的情况 (情况 1C)相同。不过, output 中可能传递不同的数据模式,需要 form 中的 additionalResponsesschema 术语。 见情况 1C 见情况 1C
情况 2C:存在 input 和多个可能的 output, output 消息使用不同的 contentType form 内的 contentTypeadditionalResponses 以及可能的 responseadditionalResponses 对具有 不同 contentType 的 output 消息需要 contentType 这是最复杂的情况,可以在 TD 中以 不同方式描述。 form 层级中的 contentType 指 input, 以及在 output 具有相同 contentType 时 指预期 output(如情况 1C)。 response 内的 contentType 在 output 具有 不同 contentType 时指预期 output (如情况 2A)。 additionalResponses 内的 contentType 指其他可能的 outputs。
  • 根据 form 层级中可用的 contentType 对 input 负载进行编码。
  • 如果所用协议允许,则将 form 层级 contentType 的值添加到 input header。
  • 如果所用协议允许,则使用 output header contentType 解码 output 负载。
  • 如果所用协议不允许或不可用,则使用 response 层级中可用的对应 contentType,或 additionalResponses 中的某个 contentType 解码 output 负载。
  • 如果所用协议允许,则使用 input header 解码 input 负载。
  • 如果所用协议不允许或不可用,则使用 form 层级中可用的对应 contentType 解码 input 负载。
  • 使用 response 层级中可用的对应 contentType,或 additionalResponses 中的某个 contentType 对 output 负载进行编码。 如果 output 与错误情况关联,则使用 带有 "success":false 的 form 中的 contentType
  • 如果所用协议允许,则将所用 contentType 的值添加到 output header。

D. JSON-LD 上下文用法

本节是非规范性的。

本规范将 TD 信息模型引入为一组 对不同词汇表的约束,即 词汇表 术语的集合。本节 简要说明如何利用 TD 文档强制要求的 @context,将这些约束的机器可读定义集成到 客户端应用中。

从 TD 文档访问 TD 信息模型分两步完成。 首先,客户端必须检索从 JSON 字符串到 IRI 的映射。该映射定义为 JSON-LD 上下文, 如后文所述。其次,客户端可以通过解引用这些 IRI, 访问在这些 IRI 上定义的约束。 约束以 RDF 格式中的逻辑公理定义, 可由客户端程序直接解释。

词汇表 术语5. TD 信息 模型中引用时,会在 TD 文档中序列化为(紧凑的)JSON 字符串。 然而,根据第一个 Linked Data 原则 [LINKED-DATA],这些术语中的每一个都由完整 IRI 明确标识。从 JSON 键到 IRI 的 映射就是 TD 的 @context 值所指向的内容。例如, 位于

https://www.w3.org/ns/wot-next/td

的文件包含以下映射(以及其他映射):

properties https://www.w3.org/2019/wot/td#hasPropertyAffordance
object https://www.w3.org/2019/wot/json-schema#ObjectSchema
basic https://www.w3.org/2019/wot/security#BasicSecurityScheme
href https://www.w3.org/2019/wot/hypermedia#hasTarget
...

该 JSON 文件遵循 JSON-LD 1.1 语法 [JSON-LD11]。 许多 JSON-LD 库可以自动处理 TD 的 @context,并扩展其中包含的所有 JSON 字符串。

一旦 TD 的每个词汇表 术语都被扩展为 IRI,第二步就是 解引用该 IRI,以获取TD 信息模型中引用 该词汇表 术语的片段。例如,解引用 IRI

https://www.w3.org/2019/wot/json-schema#ObjectSchema

会得到一个 RDF 文档,该文档声明术语 ObjectSchema 是一个,更准确地说,是 DataSchema 的子类。此类逻辑公理使用不同复杂度的形式化方法 在 RDF 中表示: 这里,子类关系表示为 RDF Schema 公理 [RDF-SCHEMA]。此外,这些公理 可以以各种格式序列化。这里,它们以 Turtle 格式 [TURTLE] 序列化:

<https://www.w3.org/2019/wot/json-schema#ObjectSchema>
    a rdfs:Class .
<https://www.w3.org/2019/wot/json-schema#ObjectSchema>
    rdfs:subClassOf <https://www.w3.org/2019/wot/json-schema#DataSchema> .

默认情况下,如果用户代理不执行任何内容 协商,则会返回人类可读的 HTML 文档, 而不是 RDF 文档。要协商内容,客户端必须在 请求中包含 HTTP header Accept: text/turtle

E. 来自 IoT 平台和标准的负载与数据 模式示例

本节是非规范性的。

作为 8.1.2.2 数据模式的扩展, 本节收集了不同负载及其对应 DataSchema 的示例。这些示例来自 知名 IoT 平台和标准,旨在说明 负载可能呈现出的各种形式,以及如何用 Data Schema 描述它。

SenML [RFC8428] 可能会 使用以下结构:

示例 82: SenML 负载示例
[
    {
        "bn": "/example/light/"
    },
    {
        "n": "level",
        "v": 50
    },
    {
        "n": "time",
        "v": 10
    }
]
示例 83:SenML 负载示例的 Data Schema
{
    "type": "array",
    "items": [
    {
        "type": "object",
        "properties": {
            "bn": {
                "type": "string",
                "const": "example/light"
            }
        }
    },
    {
        "type": "object",
        "properties": {
            "n": {
                "type": "string",
                "const": "level"
            },
            "v": {
                "@type": ["iot:LevelData"],
                "type": "integer",
                "minimum": 0,
                "maximum": 255
            }
        }
    },
    {
        "type": "object",
        "properties": {
            "n": {
                "type": "string",
                "const": "time"
            },
            "v": {
                "@type": ["iot:TransitionTimeData"],
                "type": "integer",
                "minimum": 0,
                "maximum": 65535
            }
        }
    }
    ]
}

根据 OCF[OCF],Batch Collection 可以按如下方式 结构化:

示例 84:OCF Batch 示例
[
{
    "href": "/example/light/level",
    "rep": {
    "dimmingSetting": 50
    }
},
{
    "href": "/example/light/time",
    "rep": {
    "rampTime": 10
    }
}
]
示例 85:OCF Batch 负载 示例的 Data Schema
{
"type": "array",
"items": [
    {
    "type": "object",
    "properties": {
        "href": {
        "type": "string",
        "const": "/example/light/level"
        },
        "rep": {
        "type": "object",
        "properties": {
            "dimmingSetting": {
            "@type": ["iot:LevelData"],
            "type": "integer",
            "minimum": 0,
            "maximum": 255
            }
        }
        }
    }
    },
    {
    "type": "object",
    "properties": {
        "href": {
        "type": "string",
        "const": "/example/light/time"
        },
        "rep": {
        "type": "object",
        "properties": {
            "rampTime": {
            "@type": ["iot:TransitionTimeData"],
            "type":"integer",
            "minimum": 0,
            "maximum": 65535
            }
        }
        }
    }
    }
]
}

而 LWM2M [LWM2M] 上的 IPSO Smart Object 可能如下所示:

示例 86: IPSO/LWM2M 负载示例
{
"bn": "/3001/0/",
"e": [
    {
    "n": "5044",
    "v": 0.5
    },
    {
    "n": "5002",
    "v": 10.0
    }
]
}
示例 87:IPSO/LWM2M 负载示例的 Data Schema
{
"type": "object",
"properties": {
    "bn": {
    "type": "string",
    "const": "/3001/0/"
    },
    "e": {
    "type": "array",
    "items": [
        {
        "type": "object",
        "properties": {
            "n": {
            "type": "string",
            "const": "5044"
            },
            "v": {
            "@type": ["iot:LevelData"],
            "type": "number",
            "minimum": 0.0,
            "maximum": 1.0
            }
        }
        },
        {
        "type": "object",
        "Properties": {
            "n": {
            "type": "string",
            "const": "5002"
            },
            "v": {
            "@type": ["iot:TransitionTimeData"],
            "type": "number",
            "minimum": 0.0,
            "maximum": 6553.5
            }
        }
        }
    ]
    }
}
}

F. 最近的规范变更

F.1 自 2023 年 12 月 05 日推荐标准以来的 变更

G. 致谢

编辑特别感谢 Cristiano Aguzzi、 Thomas Jäckle、Jan Romann、Elodie Thiéblin、Michael Koster、 Michael Lagally、Kazuyuki Ashimura、Daniel Peintner、Toru Kawaguchi、María Poveda、Dave Raggett、Kunihiko Toumura、 Takeshi Yamada、Ben Francis、Manu Sporny、Klaus Hartke、Addison Phillips、Jose M. Cantera、Tomoaki Mizushima、Soumya Kanti Datta 和 Benjamin Klotz 提供贡献、指导 和专业知识。

此外,非常感谢 W3C 员工以及 W3C Web of Things Interest Group (WoT IG) 和 Working Group (WoT WG) 的所有其他 当前和以往活跃参与者,感谢他们的支持、 技术投入和建议,这些都推动了 本文档的改进。

最后,特别感谢 Joerg Heuer 从 WoT IG 创立之初起领导其 2 年,并指导该小组提出 WoT 构建块的概念,包括 Thing Description。

关于未列出 参考文献的临时 ReSpec 修复:[RFC6068]、[RFC3966]、 [html]、 [RFC6750]、 [RFC7519]、[RFC7797]、 [RFC8392]、[RFC7516]、 [LDML]、 [SEMVER]、 [RFC7617]、 [RFC7616]

H. 参考文献

H.1 规范性参考文献

[APPMANIFEST]
Web Application Manifest. Marcos Caceres; Kenneth Christiansen; Diego Gonzalez-Zuniga; Daniel Murphy; Christian Liebel. W3C. 2025 年 9 月 3 日。W3C 工作 草案。URL: https://www.w3.org/TR/appmanifest/
[BCP47]
Tags for Identifying Languages. A. Phillips, Ed.; M. Davis, Ed. IETF. 2009 年 9 月。最佳当前实践。 URL: https://www.rfc-editor.org/rfc/rfc5646
[ECMA-262]
ECMAScript Language Specification. Ecma International. URL: https://tc39.es/ecma262/multipage/
[eventsource]
Server-Sent Events. Ian Hickson. W3C. 2021 年 1 月 28 日。W3C 推荐标准。URL: https://www.w3.org/TR/eventsource/
[IANA-MEDIA-TYPES]
Media Types. IANA. URL: https://www.iana.org/assignments/media-types/
[iana-web-socket-registry]
IANA Registry for Websocket Subprotocols. IANA. 2019 年 5 月 24 日。URL: https://www.iana.org/assignments/websocket/websocket.xml#subprotocol-name
[json-ld11]
JSON-LD 1.1. Gregg Kellogg; Pierre-Antoine Champin; Dave Longley. W3C. 2020 年 7 月 16 日。W3C 推荐标准。URL: https://www.w3.org/TR/json-ld11/
[json-schema]
JSON Schema: A Media Type for Describing JSON Documents. Austin Wright; Henry Andrews; Ben Hutton; Greg Dennis. Internet Engineering Task Force (IETF). 2022 年 6 月 10 日。Internet-Draft。URL: https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema
[OWASP-Top-10]
OWASP Top Ten. OWASP. URL: https://owasp.org/www-project-top-ten/
[RFC2045]
Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies. N. Freed; N. Borenstein. IETF. 1996 年 11 月。草案标准。URL: https://www.rfc-editor.org/rfc/rfc2045
[RFC2046]
Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types. N. Freed; N. Borenstein. IETF. 1996 年 11 月。 草案标准。URL: https://www.rfc-editor.org/rfc/rfc2046
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. 1997 年 3 月。最佳 当前实践。URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC2616]
Hypertext Transfer Protocol -- HTTP/1.1. R. Fielding; J. Gettys; J. Mogul; H. Frystyk; L. Masinter; P. Leach; T. Berners-Lee. IETF. 1999 年 6 月。草案标准。URL: https://www.rfc-editor.org/rfc/rfc2616
[RFC3339]
Date and Time on the Internet: Timestamps. G. Klyne; C. Newman. IETF. 2002 年 7 月。拟议标准。URL: https://www.rfc-editor.org/rfc/rfc3339
[RFC3629]
UTF-8, a transformation format of ISO 10646. F. Yergeau. IETF. 2003 年 11 月。互联网标准。URL: https://www.rfc-editor.org/rfc/rfc3629
[RFC3966]
The tel URI for Telephone Numbers. H. Schulzrinne. IETF. 2004 年 12 月。拟议标准。URL: https://www.rfc-editor.org/rfc/rfc3966
[RFC3986]
Uniform Resource Identifier (URI): Generic Syntax. T. Berners-Lee; R. Fielding; L. Masinter. IETF. 2005 年 1 月。 互联网标准。URL: https://www.rfc-editor.org/rfc/rfc3986
[RFC3987]
Internationalized Resource Identifiers (IRIs). M. Duerst; M. Suignard. IETF. 2005 年 1 月。拟议标准。URL: https://www.rfc-editor.org/rfc/rfc3987
[RFC4180]
Common Format and MIME Type for Comma-Separated Values (CSV) Files. Y. Shafranovich. IETF. 2005 年 10 月。 信息性。URL: https://www.rfc-editor.org/rfc/rfc4180
[RFC4279]
Pre-Shared Key Ciphersuites for Transport Layer Security (TLS). P. Eronen, Ed.; H. Tschofenig, Ed. IETF. 2005 年 12 月。拟议标准。URL: https://www.rfc-editor.org/rfc/rfc4279
[RFC4648]
The Base16, Base32, and Base64 Data Encodings. S. Josefsson. IETF. 2006 年 10 月。拟议标准。URL: https://www.rfc-editor.org/rfc/rfc4648
[RFC5364]
Extensible Markup Language (XML) Format Extension for Representing Copy Control Attributes in Resource Lists. M. Garcia-Martin; G. Camarillo. IETF. 2008 年 10 月。拟议 标准。URL: https://www.rfc-editor.org/rfc/rfc5364
[RFC6068]
The 'mailto' URI Scheme. M. Duerst; L. Masinter; J. Zawinski. IETF. 2010 年 10 月。拟议标准。URL: https://www.rfc-editor.org/rfc/rfc6068
[RFC6570]
URI Template. J. Gregorio; R. Fielding; M. Hadley; M. Nottingham; D. Orchard. IETF. 2012 年 3 月。拟议 标准。URL: https://www.rfc-editor.org/rfc/rfc6570
[RFC6741]
Identifier-Locator Network Protocol (ILNP) Engineering Considerations. RJ Atkinson; SN Bhatti. IETF. 2012 年 11 月。实验性。URL: https://www.rfc-editor.org/rfc/rfc6741
[RFC6749]
The OAuth 2.0 Authorization Framework. D. Hardt, Ed. IETF. 2012 年 10 月。拟议标准。URL: https://www.rfc-editor.org/rfc/rfc6749
[RFC6901]
JavaScript Object Notation (JSON) Pointer. P. Bryan, Ed.; K. Zyp; M. Nottingham, Ed. IETF. 2013 年 4 月。拟议 标准。URL: https://www.rfc-editor.org/rfc/rfc6901
[RFC7252]
The Constrained Application Protocol (CoAP). Z. Shelby; K. Hartke; C. Bormann. IETF. 2014 年 6 月。拟议 标准。URL: https://www.rfc-editor.org/rfc/rfc7252
[RFC8174]
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. B. Leiba. IETF. 2017 年 5 月。最佳当前 实践。URL: https://www.rfc-editor.org/rfc/rfc8174
[RFC8252]
OAuth 2.0 for Native Apps. W. Denniss; J. Bradley. IETF. 2017 年 10 月。最佳当前实践。URL: https://www.rfc-editor.org/rfc/rfc8252
[RFC8259]
The JavaScript Object Notation (JSON) Data Interchange Format. T. Bray, Ed. IETF. 2017 年 12 月。 互联网标准。URL: https://www.rfc-editor.org/rfc/rfc8259
[RFC8288]
Web Linking. M. Nottingham. IETF. 2017 年 10 月。 拟议标准。URL: https://httpwg.org/specs/rfc8288.html
[RFC8949]
Concise Binary Object Representation (CBOR). C. Bormann; P. Hoffman. IETF. 2020 年 12 月。互联网 标准。URL: https://www.rfc-editor.org/rfc/rfc8949
[RFC9112]
HTTP/1.1. R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed. IETF. 2022 年 6 月。互联网标准。URL: https://httpwg.org/specs/rfc9112.html
[SEMVER]
Semantic Versioning 2.0.0. Tom Preston-Werner. 2017 年 12 月 26 日。 URL: https://semver.org/
[STRING-META]
Strings on the Web: Language and Direction Metadata. Richard Ishida; Addison Phillips. W3C. 2024 年 10 月 17 日。W3C 工作组说明。URL: https://www.w3.org/TR/string-meta/
[websub]
WebSub. Julien Genestoux; Aaron Parecki. W3C. 2018 年 1 月 23 日。 W3C 推荐标准。URL: https://www.w3.org/TR/websub/
[WOT-ARCHITECTURE]
Web of Things (WoT) Architecture 1.1. Michael Lagally; Ryuichi Matsukura; Kunihiko Toumura. W3C. 2020 年 11 月。URL: https://www.w3.org/TR/wot-architecture11/
[wot-architecture11]
Web of Things (WoT) Architecture 1.1. Michael Lagally; Ryuichi Matsukura; Kunihiko Toumura; Michael McCool. W3C. 2023 年 12 月 5 日。W3C 推荐标准。URL: https://www.w3.org/TR/wot-architecture11/
[WOT-BINDING-REGISTRY]
Web of Things (WoT) Binding Registry. Ege Korkan. W3C. TODO. URL: https://www.w3.org/TR/wot-binding-registry/
[WOT-PROFILES]
Web of Things (WoT) Profile. Michael Lagally; Michael McCool; Ryuichi Matsukura; Sebastian Kaebisch; Tomoaki Mizushima. W3C. 2020 年 11 月。URL: https://www.w3.org/TR/wot-profile/
[WOT-SECURITY-GUIDELINES]
Web of Things (WoT) Security and Privacy Guidelines. Michael McCool; Elena Reshetova. W3C. 2021 年 7 月。URL: https://w3c.github.io/wot-security/
[WOT-THING-DESCRIPTION]
Web of Things (WoT) Thing Description. Sebastian Käbisch; Takuki Kamiya; Michael McCool; Victor Charpenay; Matthias Kovatsch. W3C. 2020 年 4 月 9 日。W3C 推荐标准。 URL: https://www.w3.org/TR/wot-thing-description/
[wot-thing-description10]
Web of Things (WoT) Thing Description. Sebastian Käbisch; Takuki Kamiya; Michael McCool; Victor Charpenay; Matthias Kovatsch. W3C. 2020 年 4 月 9 日。W3C 推荐标准。 URL: https://www.w3.org/TR/wot-thing-description10/
[XML]
Extensible Markup Language (XML) 1.0 (Fifth Edition). Tim Bray; Jean Paoli; Michael Sperberg-McQueen; Eve Maler; François Yergeau et al. W3C. 2008 年 11 月 26 日。W3C 推荐标准。URL: https://www.w3.org/TR/xml/
[XMLSCHEMA11-2-20120405]
W3C XML Schema Definition Language (XSD) 1.1 Part 2: Datatypes. David Peterson; Sandy Gao; Ashok Malhotra; Michael Sperberg-McQueen; Henry Thompson; Paul V. Biron et al. W3C. 2012 年 4 月 5 日。W3C 推荐标准。 URL: https://www.w3.org/TR/2012/REC-xmlschema11-2-20120405/

H.2 资料性参考文献

[html]
HTML Standard. Anne van Kesteren; Domenic Denicola; Dominic Farolino; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. 现行标准。URL: https://html.spec.whatwg.org/multipage/
[HTTP-in-RDF10]
HTTP Vocabulary in RDF 1.0. Johannes Koch; Carlos A. Velasco; Philip Ackermann. W3C. 2017 年 2 月 2 日。W3C 工作组说明。URL: https://www.w3.org/TR/HTTP-in-RDF10/
[IANA-URI-SCHEMES]
Uniform Resource Identifier (URI) Schemes. IANA. URL: https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml
[JSON-SCHEMA-ONTOLOGY]
JSON Schema in RDF. Victor Charpenay; Maxime Lefrançois; María Poveda Villalón. W3C. 2022 年 7 月。URL: https://www.w3.org/2019/wot/json-schema
[LDML]
Unicode Technical Standard #35: Unicode Locale Data Markup Language (LDML). Mark Davis; CLDR Contributors. 2022 年 3 月。URL: https://unicode.org/reports/tr35/
[LINKED-DATA]
Linked Data Design Issues. Tim Berners-Lee. W3C. 2006 年 7 月 27 日。W3C 内部文档。URL: https://www.w3.org/DesignIssues/LinkedData.html
[LINKSET-MEDIA-TYPES]
Linkset: Media Types and a Link Relation Type for Link Sets. Erik Wilde; Herbert Van de Sompel. IETF. URL: https://datatracker.ietf.org/doc/draft-ietf-httpapi-linkset/
[LWM2M]
Lightweight M2M. Open Mobility Alliance. URL: https://www.omaspecworks.org/what-is-oma-specworks/iot/lightweight-m2m-lwm2m/
[MQTT]
MQTT Version 3.1.1. Andrew Banks; Rahul Gupta. OASIS. 2015 年 12 月。包含已批准勘误 01 的 OASIS 标准。URL: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html
[OCF]
OCF Specification. Open Connectivity Foundation. 最后访问:2020 年 2 月。URL: https://openconnectivity.org/developer/specifications/
[OPENAPI]
OpenAPI Specification: Version 3.0.1. Darrel Miller; Jeremy Whitlock; Marsh Gardiner; Mike Ralphson; Ron Ratovsky; Uri Sarid. OpenAPI Initiative, Linux Foundation. 2017 年 12 月 6 日。URL: https://spec.openapis.org/oas/v3.0.1
[RDF-SCHEMA]
RDF Schema 1.1. Dan Brickley; Ramanathan Guha. W3C. 2014 年 2 月 25 日。W3C 推荐标准。URL: https://www.w3.org/TR/rdf-schema/
[RFC6750]
The OAuth 2.0 Authorization Framework: Bearer Token Usage. M. Jones; D. Hardt. IETF. 2012 年 10 月。 拟议标准。URL: https://www.rfc-editor.org/rfc/rfc6750
[RFC7516]
JSON Web Encryption (JWE). M. Jones; J. Hildebrand. IETF. 2015 年 5 月。拟议标准。URL: https://www.rfc-editor.org/rfc/rfc7516
[RFC7519]
JSON Web Token (JWT). M. Jones; J. Bradley; N. Sakimura. IETF. 2015 年 5 月。拟议标准。URL: https://www.rfc-editor.org/rfc/rfc7519
[RFC7616]
HTTP Digest Access Authentication. R. Shekh-Yusef, Ed.; D. Ahrens; S. Bremer. IETF. 2015 年 9 月。拟议 标准。URL: https://httpwg.org/specs/rfc7616.html
[RFC7617]
The 'Basic' HTTP Authentication Scheme. J. Reschke. IETF. 2015 年 9 月。拟议标准。URL: https://httpwg.org/specs/rfc7617.html
[RFC7797]
JSON Web Signature (JWS) Unencoded Payload Option. M. Jones. IETF. 2016 年 2 月。拟议标准。URL: https://www.rfc-editor.org/rfc/rfc7797
[RFC8392]
CBOR Web Token (CWT). M. Jones; E. Wahlstroem; S. Erdtman; H. Tschofenig. IETF. 2018 年 5 月。拟议 标准。URL: https://www.rfc-editor.org/rfc/rfc8392
[RFC8428]
Sensor Measurement Lists (SenML). C. Jennings; Z. Shelby; J. Arkko; A. Keranen; C. Bormann. IETF. 2018 年 8 月。 拟议标准。URL: https://www.rfc-editor.org/rfc/rfc8428
[RFC9200]
Authentication and Authorization for Constrained Environments Using the OAuth 2.0 Framework (ACE-OAuth). L. Seitz; G. Selander; E. Wahlstroem; S. Erdtman; H. Tschofenig. IETF. 2022 年 8 月。拟议标准。URL: https://www.rfc-editor.org/rfc/rfc9200
[sdw-bp]
Spatial Data on the Web Best Practices. Payam Barnaghi; Jeremy Tandy; Linda van den Brink; Timo Homburg. W3C. 2023 年 9 月 19 日。DNOTE。URL: https://www.w3.org/TR/sdw-bp/
[SMARTM2M]
ETSI TS 103 264 V4.1.1 (2025-03): SmartM2M; Smart Applications; Reference Ontology and oneM2M Mapping. ETSI. 2025 年 3 月。已发布。URL: http://www.etsi.org/deliver/etsi_ts/103200_103299/103264/04.01.01_60/ts_103264v040101p.pdf
[TURTLE]
RDF 1.1 Turtle. Eric Prud'hommeaux; Gavin Carothers. W3C. 2014 年 2 月 25 日。W3C 推荐标准。URL: https://www.w3.org/TR/turtle/
[VOCAB-SSN]
Semantic Sensor Network Ontology. Armin Haller; Krzysztof Janowicz; Simon Cox; Danh Le Phuoc; Kerry Taylor; Maxime Lefrançois. W3C. 2017 年 10 月 19 日。W3C 推荐标准。URL: https://www.w3.org/TR/vocab-ssn-2017/
[w3c-basic-geo]
Basic Geo (WGS84 lat/long) Vocabulary. Dan Brickley. W3C Semantic Web Interest Group. 2006 年 2 月 1 日。URL: https://www.w3.org/2003/01/geo/
[WOT-BINDING-TEMPLATES]
Web of Things (WoT) Binding Templates. Michael Koster; Ege Korkan. W3C. 2024 年 5 月 28 日。W3C 工作组 说明。URL: https://www.w3.org/TR/wot-binding-templates/
[WOT-DISCOVERY]
Web of Things (WoT) Discovery. Kunihiko Toumura; Michael McCool; Andrea Cimmino; Farshid Tavakolizadeh. W3C. 2023 年 12 月 5 日。W3C 推荐标准。URL: https://www.w3.org/TR/wot-discovery/
[WOT-THING-DESCRIPTION11]
Web of Things (WoT) Thing Description 1.1. Sebastian Käbisch; Michael McCool; Ege Korkan. W3C. 2023 年 12 月 5 日。W3C 推荐标准。URL: https://www.w3.org/TR/wot-thing-description11/