• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

json-patch-4.2.0/H03-Feb-2019-

.travis.ymlH A D06-Oct-2020259

LICENSEH A D06-Oct-20201.5 KiB

README.mdH A D06-Oct-20207.8 KiB

errors.goH A D06-Oct-20201.2 KiB

merge.goH A D06-Oct-20208.6 KiB

patch.goH A D06-Oct-202012 KiB

README.md

1# JSON-Patch
2`jsonpatch` is a library which provides functionallity for both applying
3[RFC6902 JSON patches](http://tools.ietf.org/html/rfc6902) against documents, as
4well as for calculating & applying [RFC7396 JSON merge patches](https://tools.ietf.org/html/rfc7396).
5
6[![GoDoc](https://godoc.org/github.com/evanphx/json-patch?status.svg)](http://godoc.org/github.com/evanphx/json-patch)
7[![Build Status](https://travis-ci.org/evanphx/json-patch.svg?branch=master)](https://travis-ci.org/evanphx/json-patch)
8[![Report Card](https://goreportcard.com/badge/github.com/evanphx/json-patch)](https://goreportcard.com/report/github.com/evanphx/json-patch)
9
10# Get It!
11
12**Latest and greatest**:
13```bash
14go get -u github.com/evanphx/json-patch
15```
16
17**Stable Versions**:
18* Version 4: `go get -u gopkg.in/evanphx/json-patch.v4`
19
20(previous versions below `v3` are unavailable)
21
22# Use It!
23* [Create and apply a merge patch](#create-and-apply-a-merge-patch)
24* [Create and apply a JSON Patch](#create-and-apply-a-json-patch)
25* [Comparing JSON documents](#comparing-json-documents)
26* [Combine merge patches](#combine-merge-patches)
27
28
29# Configuration
30
31* There is a global configuration variable `jsonpatch.SupportNegativeIndices`.
32  This defaults to `true` and enables the non-standard practice of allowing
33  negative indices to mean indices starting at the end of an array. This
34  functionality can be disabled by setting `jsonpatch.SupportNegativeIndices =
35  false`.
36
37* There is a global configuration variable `jsonpatch.AccumulatedCopySizeLimit`,
38  which limits the total size increase in bytes caused by "copy" operations in a
39  patch. It defaults to 0, which means there is no limit.
40
41## Create and apply a merge patch
42Given both an original JSON document and a modified JSON document, you can create
43a [Merge Patch](https://tools.ietf.org/html/rfc7396) document.
44
45It can describe the changes needed to convert from the original to the
46modified JSON document.
47
48Once you have a merge patch, you can apply it to other JSON documents using the
49`jsonpatch.MergePatch(document, patch)` function.
50
51```go
52package main
53
54import (
55	"fmt"
56
57	jsonpatch "github.com/evanphx/json-patch"
58)
59
60func main() {
61	// Let's create a merge patch from these two documents...
62	original := []byte(`{"name": "John", "age": 24, "height": 3.21}`)
63	target := []byte(`{"name": "Jane", "age": 24}`)
64
65	patch, err := jsonpatch.CreateMergePatch(original, target)
66	if err != nil {
67		panic(err)
68	}
69
70	// Now lets apply the patch against a different JSON document...
71
72	alternative := []byte(`{"name": "Tina", "age": 28, "height": 3.75}`)
73	modifiedAlternative, err := jsonpatch.MergePatch(alternative, patch)
74
75	fmt.Printf("patch document:   %s\n", patch)
76	fmt.Printf("updated alternative doc: %s\n", modifiedAlternative)
77}
78```
79
80When ran, you get the following output:
81
82```bash
83$ go run main.go
84patch document:   {"height":null,"name":"Jane"}
85updated tina doc: {"age":28,"name":"Jane"}
86```
87
88## Create and apply a JSON Patch
89You can create patch objects using `DecodePatch([]byte)`, which can then
90be applied against JSON documents.
91
92The following is an example of creating a patch from two operations, and
93applying it against a JSON document.
94
95```go
96package main
97
98import (
99	"fmt"
100
101	jsonpatch "github.com/evanphx/json-patch"
102)
103
104func main() {
105	original := []byte(`{"name": "John", "age": 24, "height": 3.21}`)
106	patchJSON := []byte(`[
107		{"op": "replace", "path": "/name", "value": "Jane"},
108		{"op": "remove", "path": "/height"}
109	]`)
110
111	patch, err := jsonpatch.DecodePatch(patchJSON)
112	if err != nil {
113		panic(err)
114	}
115
116	modified, err := patch.Apply(original)
117	if err != nil {
118		panic(err)
119	}
120
121	fmt.Printf("Original document: %s\n", original)
122	fmt.Printf("Modified document: %s\n", modified)
123}
124```
125
126When ran, you get the following output:
127
128```bash
129$ go run main.go
130Original document: {"name": "John", "age": 24, "height": 3.21}
131Modified document: {"age":24,"name":"Jane"}
132```
133
134## Comparing JSON documents
135Due to potential whitespace and ordering differences, one cannot simply compare
136JSON strings or byte-arrays directly.
137
138As such, you can instead use `jsonpatch.Equal(document1, document2)` to
139determine if two JSON documents are _structurally_ equal. This ignores
140whitespace differences, and key-value ordering.
141
142```go
143package main
144
145import (
146	"fmt"
147
148	jsonpatch "github.com/evanphx/json-patch"
149)
150
151func main() {
152	original := []byte(`{"name": "John", "age": 24, "height": 3.21}`)
153	similar := []byte(`
154		{
155			"age": 24,
156			"height": 3.21,
157			"name": "John"
158		}
159	`)
160	different := []byte(`{"name": "Jane", "age": 20, "height": 3.37}`)
161
162	if jsonpatch.Equal(original, similar) {
163		fmt.Println(`"original" is structurally equal to "similar"`)
164	}
165
166	if !jsonpatch.Equal(original, different) {
167		fmt.Println(`"original" is _not_ structurally equal to "similar"`)
168	}
169}
170```
171
172When ran, you get the following output:
173```bash
174$ go run main.go
175"original" is structurally equal to "similar"
176"original" is _not_ structurally equal to "similar"
177```
178
179## Combine merge patches
180Given two JSON merge patch documents, it is possible to combine them into a
181single merge patch which can describe both set of changes.
182
183The resulting merge patch can be used such that applying it results in a
184document structurally similar as merging each merge patch to the document
185in succession.
186
187```go
188package main
189
190import (
191	"fmt"
192
193	jsonpatch "github.com/evanphx/json-patch"
194)
195
196func main() {
197	original := []byte(`{"name": "John", "age": 24, "height": 3.21}`)
198
199	nameAndHeight := []byte(`{"height":null,"name":"Jane"}`)
200	ageAndEyes := []byte(`{"age":4.23,"eyes":"blue"}`)
201
202	// Let's combine these merge patch documents...
203	combinedPatch, err := jsonpatch.MergeMergePatches(nameAndHeight, ageAndEyes)
204	if err != nil {
205		panic(err)
206	}
207
208	// Apply each patch individual against the original document
209	withoutCombinedPatch, err := jsonpatch.MergePatch(original, nameAndHeight)
210	if err != nil {
211		panic(err)
212	}
213
214	withoutCombinedPatch, err = jsonpatch.MergePatch(withoutCombinedPatch, ageAndEyes)
215	if err != nil {
216		panic(err)
217	}
218
219	// Apply the combined patch against the original document
220
221	withCombinedPatch, err := jsonpatch.MergePatch(original, combinedPatch)
222	if err != nil {
223		panic(err)
224	}
225
226	// Do both result in the same thing? They should!
227	if jsonpatch.Equal(withCombinedPatch, withoutCombinedPatch) {
228		fmt.Println("Both JSON documents are structurally the same!")
229	}
230
231	fmt.Printf("combined merge patch: %s", combinedPatch)
232}
233```
234
235When ran, you get the following output:
236```bash
237$ go run main.go
238Both JSON documents are structurally the same!
239combined merge patch: {"age":4.23,"eyes":"blue","height":null,"name":"Jane"}
240```
241
242# CLI for comparing JSON documents
243You can install the commandline program `json-patch`.
244
245This program can take multiple JSON patch documents as arguments,
246and fed a JSON document from `stdin`. It will apply the patch(es) against
247the document and output the modified doc.
248
249**patch.1.json**
250```json
251[
252    {"op": "replace", "path": "/name", "value": "Jane"},
253    {"op": "remove", "path": "/height"}
254]
255```
256
257**patch.2.json**
258```json
259[
260    {"op": "add", "path": "/address", "value": "123 Main St"},
261    {"op": "replace", "path": "/age", "value": "21"}
262]
263```
264
265**document.json**
266```json
267{
268    "name": "John",
269    "age": 24,
270    "height": 3.21
271}
272```
273
274You can then run:
275
276```bash
277$ go install github.com/evanphx/json-patch/cmd/json-patch
278$ cat document.json | json-patch -p patch.1.json -p patch.2.json
279{"address":"123 Main St","age":"21","name":"Jane"}
280```
281
282# Help It!
283Contributions are welcomed! Leave [an issue](https://github.com/evanphx/json-patch/issues)
284or [create a PR](https://github.com/evanphx/json-patch/compare).
285
286
287Before creating a pull request, we'd ask that you make sure tests are passing
288and that you have added new tests when applicable.
289
290Contributors can run tests using:
291
292```bash
293go test -cover ./...
294```
295
296Builds for pull requests are tested automatically
297using [TravisCI](https://travis-ci.org/evanphx/json-patch).
298