文档:https://pkg.go.dev/github.com/evanphx/json-patch
Func
// CreateMergePatch 返回从 original 到 modified 需要做改动,也就是patch
func CreateMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error)
// MergePatch 将docData 做 patch 改动
func MergePatch(docData, patchData []byte) ([]byte, error)
// Equal 比较两个json是否相等
func Equal(a, b []byte) bool
type Patch
type Patch []Operation
func DecodePatch(buf []byte) (Patch, error)
func (p Patch) Apply(doc []byte) ([]byte, error)
type Operation
type Operation map[string]*json.RawMessage
func (o Operation) From() (string, error)
func (o Operation) Kind() string // reads the "op" field of the Operation
func (o Operation) Path() (string, error) // reads the "path" field of the Operation
func (o Operation) ValueInterface() (interface{}, error)
Demo
Combine merge patches
func main() {
original := []byte(`{"name": "John", "age": 24, "height": 3.21}`)
target := []byte(`{"name": "Jane", "age": 24, "money":1}`)
patch, err := jsonpatch.CreateMergePatch(original, target)
if err != nil {
panic(err)
}
fmt.Println(string(patch))
// {"height":null,"money":1,"name":"Jane"}
alternative := []byte(`{"name": "Tina", "age": 28, "height": 3.75}`)
modifiedAlternative, err := jsonpatch.MergePatch(alternative, patch)
fmt.Println(string(modifiedAlternative))
// {"age":28,"money":1,"name":"Jane"}
}
apply a merge patch
func main() {
patchJSON := []byte(`[
{"op": "replace", "path": "/name", "value": "Jane"},
{"op": "remove", "path": "/height"},
{"op": "add", "path": "/money", "value": 100},
{"op": "add", "path": "/obj/key", "value": "val"}
]`)
original := []byte(`{"name": "John", "age": 24, "height": 3.21, "obj":{}}`)
patch, err := jsonpatch.DecodePatch(patchJSON)
if err != nil {
panic(err)
}
modified, err := patch.Apply(original)
if err != nil {
panic(err)
}
fmt.Println(string(modified))
// {"age":24,"money":100,"name":"Jane","obj":{"key":"val"}}
}