JSON Patch 跳脫 (Escape) 小 memo



前言

  • 在調整 kustomize 的時候,發現 labels 裡面帶斜線 / 的資源,在 patch 時會有問題。
  • 剛好在 [2] 看到解答 (RFC 其實也有定義 [1]),也藉機會整理一下 JSON Patch 的跳脫。
  • 結論:/ 要用 ~1 取代。



直接上範例

置換 .a.b

假設這是我們的 JSON data

1
2
3
4
5
6
7
8
9
{
    "a": {
        "b": "=========="
    },
    "a~01b": "==========",
    "a~1b": "==========",
    "a/b": "==========",
    "/a/b": "=========="
}

一般情況下,如果要用 JSON Patch 替換 .a.b 的值,可以這樣做:

1
2
3
4
5
6
7
[
    {
        "op": "replace",
        "path": "/a/b",
        "value": "replaced!"
    }
]

可以順利置換:

1
2
3
4
5
6
7
8
9
{
    "a": {
        "b": "replaced!"
    },
    "a~01b": "==========",
    "a~1b": "==========",
    "a/b": "==========",
    "/a/b": "=========="
}



置換 .a/b

把 key 中的 / 換成 ~1;最上層的路徑斜線還是要保留:

1
2
3
4
5
6
7
[
    { 
        "op": "replace", 
        "path": "/a~1b", 
        "value": "replaced!"
    }
]

結果

1
2
3
4
5
6
7
8
9
{
    "a": {
        "b": "=========="
    },
    "a~01b": "==========",
    "a~1b": "==========",
    "a/b": "replaced!",
    "/a/b": "=========="
}



置換 ./a/b

同理,把 key 中的 / 全部換成 ~1

1
2
3
4
5
6
7
[
    { 
        "op": "replace", 
        "path": "/~1a~1b", 
        "value": "replaced!"
    }
]

結果

1
2
3
4
5
6
7
8
9
{
    "a": {
        "b": "=========="
    },
    "a~01b": "==========",
    "a~1b": "==========",
    "a/b": "==========",
    "/a/b": "replaced!"
}



置換 .a~1b

要是很不幸地,你的 key 中間剛好有 ~1,就要把 ~ 換成 ~0 (或是想成在 ~1 之間補一個 0),

最後就是把 ~1 替換成 ~01

1
2
3
4
5
6
7
[
    { 
        "op": "replace", 
        "path": "/a~01b", 
        "value": "replaced!"
    }
]

結果

1
2
3
4
5
6
7
8
9
{
    "a": {
        "b": "=========="
    },
    "a~01b": "==========",
    "a~1b": "replaced!",
    "a/b": "==========",
    "/a/b": "=========="
}



置換 .a~01b

要是又更不幸地,你的 key 中間剛好有 ~01,就以此類推,繼續把 ~ 置換成 ~0 (也可以想成再補 0)

最後就是把 ~01 寫成 ~001

1
2
3
4
5
6
7
[
    { 
        "op": "replace", 
        "path": "/a~001b", 
        "value": "replaced!"
    }
]

結果

1
2
3
4
5
6
7
8
9
{
    "a": {
        "b": "=========="
    },
    "a~01b": "replaced!",
    "a~1b": "==========",
    "a/b": "==========",
    "/a/b": "=========="
}



小工具

可以用線上工具來測試 patch 結果:




REF

  1. https://datatracker.ietf.org/doc/html/rfc6902#appendix-A.14
  2. https://github.com/kubernetes-sigs/kustomize/issues/1256

主題 StackJimmy 設計