JSON Patch
JSON Path是在使用Kubernetes API的过程中首次使用的. 使用API做扩缩容的时候, 发送整个Deployment的全文不是个明智的做法, 虽然可行. 因此便使用了JSON Patch.
JsonObject item = new JsonObject();
item.add("op", new JsonPrimitive("replace"));
item.add("path", new JsonPrimitive("/spec/replicas"));
item.add("value", new JsonPrimitive(instances));
JsonArray body = new JsonArray();
body.add(item);
appsV1beta1Api.patchNamespacedScaleScale(id, namespace, body, null);
fabric8s提供的kubernetes-client中使用的zjsonpatch则封装了JSON Patch操作. 例如在做扩缩容的时候或者当前的deployment, 修改replicas的值. 然后比较对象的不同(JsonDiff.asJson(sourceJsonNode, targetJsonNode)).
下面的内容部分翻译自JSON PATH, 有兴趣的可以跳转看原文.
什么是JSON Patch
JSON Path是一直描述JSON文档变化的格式. 使用它可以避免在只需要修改某一部分的时候发送整个文档内容. 当与HTTP PATCH方法混合使用的时候, 它允许在标准规范的基础上使用HTTP APIs进行部分更新.
补丁(Patch)内容的格式也是JSON.
JSON Patch由IETF在RFC 6902中规范.
简单的例子
原始文档
{
"baz": "qux",
"foo": "bar"
}
补丁
[
{ "op": "replace", "path": "/baz", "value": "boo" },
{ "op": "add", "path": "/hello", "value": ["world"] },
{ "op": "remove", "path": "/foo"}
]
结果
{
"baz": "boo",
"hello": ["world"]
}
如何实现
一个JSON Path文档是一个包含了一组patch操作的JSON文件. 支持的patch操作包括"add", “remove”, “replace”, “move”, “copy"和"test”. 这些patch操作是按照顺序应用的: 如果有任何一个操作失败, 整个patch都会被终止.
JSON Pointer(指针)
JSON指针IETF RFC 6901定义了一个如何在JSON文档中定位指定值的字符格式. 用来在所有的JSON Patch操作中指定要修改的文档部分.
JSON指针是使用/
分隔的token字符串, 这些token指定了对象的key或者是数组的索引. 例如, 给定JSON
{
"biscuits": [
{ "name": "Digestive" },
{ "name": "Choco Leibniz" }
]
}
/biscuits
将指向数组biscuits, 同时/biscuits/1/name
指向Choco Leibniz
.
要指向JSON文档的根要使用一个空的字符串''
. 指针/
并不是指向根, 而是指向根上key为""
的位置(在JSON中是非法的).
操作
Add
{ "op": "add", "path": "/biscuits/1", "value": { "name": "Ginger Nut" } }
在对象上增加一个值, 或者数组中插入数据. 如果是数组, 值将被插入到给定位置的前面. -
用来表示插入到数组的尾部.
Remove
{ "op": "remove", "path": "/biscuits" }
删除对象或者数组中的值.
Replace
{ "op": "replace", "path": "/biscuits/0/name", "value": "Chocolate Digestive" }
替换一个值. 等同于先删除再增加.
Copy
{ "op": "copy", "from": "/biscuits/0", "path": "/best_biscuit" }
从一个位置(from)复制数据到指定的位置(path)上. from
和to
都是JSON指针.
Move
{ "op": "move", "from": "/biscuits", "path": "/cookies" }
从一个位置(from)移动数据到指定的位置(path)上. from
和to
都是JSON指针.
Test
{ "op": "test", "path": "/best_biscuit/name", "value": "Choco Leibniz" }
检查某个位置的值是否是指定的值.如果失败, 整个Patch操作就会终止.
库
JavaScript
Python
PHP
Ruby
Perl
C
- cJSON (JSON library in C, includes JSON Patch support in cJSON_Utils)
Java
Scala
C++
C####
- Ramone (a framework for consuming REST services, includes a JSON Patch implementation)
- JsonPatch (Adds JSON Patch support to ASP.NET Web API)
- Starcounter (In-memory Application Engine, uses JSON Patch with OT for client-server sync)
- Nancy.JsonPatch (Adds JSON Patch support to NancyFX)
Go
Haskell
Erlang
Elm
测试套件
github上维护的一组一致性测试 github.com/json-patch/json-patch-tests