跳到主要内容

1. 引言

URI [RFC3986] 非常常见地包含结构化应用数据. 这些数据可能包括文件系统产生的构件 (通常出现在 path 组件中) 和用户信息 (通常出现在 query 组件中). 在某些情况下, authority 组件中甚至也可能存在应用专用数据 (例如, 某些应用分布在多个主机名上, 以实现某种形式的分区或分派).

实现可以进一步约束 URI 的结构. 例如, 许多 Web 服务器使用最后一个 path segment 的文件扩展名来确定响应的 media type. 同样, 预打包应用通常具有高度结构化的 URI, 而且只能以有限方式变更 (通常只是变更其部署所在的主机名和端口).

由于 URI 的所有者 (如 [webarch] Section 2.2.2.1 所定义) 选择使用该服务器或应用, 这可以被视为对权限的合理委托. 然而, 当这类约定由所有者以外的一方强制规定时, 可能产生若干潜在有害影响:

  • Collisions - 随着越来越多针对 URI 结构的 ad hoc 约定被标准化, 这些约定之间发生冲突的可能性会增加 (尤其考虑到服务器, 应用和单独部署也会有各自的约定).

  • Dilution - 当添加到 URI 的信息是短暂的时, 它会降低 URI 的稳定性 (见 [webarch] Section 3.5.1), 从而削弱 URI 的实用性, 并可能导致同一 URI 存在多种替代形式 (见 [webarch] Section 2.3.1).

  • Rigidity - 固定的 URI 语法经常干扰期望的部署模式. 例如, 如果某个 authority 希望在单个主机名上提供多个应用, 而这些应用的 URI 又不允许所需的灵活性, 那么这样做会变得困难甚至不可能.

  • Operational Difficulty - 支持某些 URI 约定在一些实现中可能很困难. 例如, 指定某个特定 query 参数必须与 "http" URI 一起使用, 可能会排除使用从文件系统提供响应的 Web 服务器. 同样, 固定其运行 base path 的应用 (例如 "/v1") 会使得无法在同一主机上以相同前缀部署其他应用.

  • Client Assumptions - 当约定被标准化后, 一些客户端在看到这些约定时将不可避免地假定相关标准正在被使用. 这可能导致互操作性问题. 例如, 如果某个规范记载 URI query 参数 "sig" 表示其载荷是该 URI 的加密签名, 则可能导致不期望的行为.

因此, 发布一个以 [RFC3986] 未明确允许的方式约束现有 URI 结构的标准 (通常是通过更新 URI scheme 定义) 有时会产生问题. 原因既包括上述因素, 也包括 URI 的结构需要牢固地处于其所有者控制之下.

本文档说明在标准中建立 URI 结构, 约定和格式时的一些当前最佳实践. 它还在 Section 3 中为规范提供若干策略.

1.1. 目标读者

本文档的指南和要求面向那些约束 URI 或其组成部分的语法或结构的规范作者. 其中明确指出两类此类规范:

  • Protocol Extensions ("Extensions") - 提供新能力的规范, 这些能力可适用于任何标识符或大量可能标识符的子集. 例如, 用于 "http" URI 的新签名机制, 用于任何 URI 的 metadata, 或一种新格式.

  • Applications Using URIs ("Applications") - 使用 URI 满足特定需求的规范. 例如, 到主机上特定信息的 HTTP 接口.

面向通用类别 "Specifications" 的要求适用于所有规范, 包括上面列举的两类规范以及其他规范.

注意, 本规范不应被解释为阻止那些合法拥有 URI 或已被委托该所有权的各方分配 URI 控制权. 例如, 某个规范可以在建立注册表的过程中, 合法地定义 IANA Web 站点上某个 URI 的语义.

可能已有一些 IETF 规范偏离了本文档中的指导. 在这些情况下, 应由相关社区 (即 URI scheme 的社区以及产生该规范的任何相关社区) 确定适当结果, 例如更新 scheme 定义或修改该规范.

1.2. 记法约定

本文档中的关键词 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" 和 "OPTIONAL" 在且仅在以此处所示全大写形式出现时, 应按 BCP 14 [RFC2119] [RFC8174] 中的描述解释.