json rfc rfc6901 rfc6902 rfc7396 api-design standards

JSON 标准指南:RFC 6901 (Pointer), 6902 (Patch) 与 7396 (Merge Patch) 详解

掌握 JSON 处理标准。深入理解 RFC 6901, RFC 6902 和 RFC 7396 如何提供标准化的 JSON 数据定位与修改方式。

2026-04-11

JSON 标准指南:RFC 6901, 6902 和 7396

JSON 已成为 Web 数据交换的事实标准。然而,随着 API 变得越来越复杂,简单的 JSON 对象往往不够用。开发者需要标准化的方法来引用 JSON 文档的具体部分,并描述对这些文档的更改。这就是 RFC 6901 (JSON Pointer)RFC 6902 (JSON Patch)RFC 7396 (JSON Merge Patch) 的用武之地。

什么是 JSON Pointer 和 Patch?

  • RFC 6901 (JSON Pointer):定义了一种字符串语法,用于标识 JSON 文档中的特定值。它就像数据的“地址”。
  • RFC 6902 (JSON Patch):定义了一种 JSON 文档结构,用于表达要应用于 JSON 文档的一系列操作。它就像“差异”或“事务日志”。
  • RFC 7396 (JSON Merge Patch):提供了一种描述更改的更简单方法,即发送一个看起来像目标文档但仅包含更改字段的“补丁”文档。

1. RFC 6901: JSON Pointer

JSON Pointer 使用正斜杠 (/) 分隔的语法来导航 JSON 对象的层次结构。

语法规则:

  • / 表示根。
  • /foo 指向 "foo" 键的值。
  • /foo/0 指向 "foo" 数组的第一个元素。
  • ~1 用于表示字面量 /
  • ~0 用于表示字面量 ~

示例:

{
  "biscuits": [
    { "name": "Digestive" },
    { "name": "Choco" }
  ]
}

Pointer /biscuits/1/name 将解析为 "Choco"

2. RFC 6902: JSON Patch

JSON Patch 是一个操作对象数组。每个对象必须有一个 op 字段。

操作:

  • add:在指定路径添加值。
  • remove:移除路径处的值。
  • replace:替换路径处的值。
  • move:将值从一个路径移动到另一个路径。
  • copy:将值从一个路径复制到另一个路径。
  • test:测试路径处的值是否符合预期。

补丁示例:

[
  { "op": "replace", "path": "/biscuits/0/name", "value": "Oatmeal" },
  { "op": "add", "path": "/biscuits/-", "value": { "name": "Ginger" } }
]

/biscuits/- 中的 - 表示“数组末尾”。

3. RFC 7396: JSON Merge Patch

JSON Merge Patch 比 RFC 6902 简单得多。您只需发送一个 JSON 对象,该对象表示您要更改的字段的最终状态。

规则:

  • 如果补丁包含具有非空值的字段,则更新或添加该字段。
  • 如果补丁包含具有 null 值的字段,则从目标中移除该字段。
  • 它不适合修补数组(它会替换整个数组)。

示例:

目标:

{ "a": "b", "c": "d" }

补丁:

{ "a": "z", "c": null, "e": "f" }

结果:

{ "a": "z", "e": "f" }
}

比较:Patch vs. Merge Patch

特性 RFC 6902 (Patch) RFC 7396 (Merge Patch)
复杂度 高(操作数组) 低(基于对象)
效率 极高(手术级修改) 中等(字段级)
数组支持 完全支持 较差(替换整个数组)
原子操作 是(test 操作)
适用场景 复杂状态更改 简单属性更新

常见问题 FAQ

问:我的 API 应该使用哪一个? 答:对于不需要精确数组操作的简单资源更新,请使用 JSON Merge Patch (7396)。对于复杂资源、高性能要求或需要原子“测试并设置”操作的情况,请使用 JSON Patch (6902)

问:我可以在 URL 中使用 JSON Pointer 吗? 答:可以,在 URI 片段中使用 JSON Pointer 很常见(例如 example.com/schema.json#/definitions/user)。

问:如何处理键中的特殊字符? 答:使用 ~1 表示 /,使用 ~0 表示 ~。例如,名为 a/b 的键引用为 /a~1b

相关工具