An implementation of RFC 6902 in pure Elixir.
Features:
- Creating a patch by comparing to maps and structs
- Apply patches to maps and structs - supports operations:
- add
- replace
- remove
- copy
- move
- test
- De/Encoding and mapping
- Escaping of "
/
" (by "~1
") and "~
" (by "~0
") - Allow usage of
-
for appending things to list (Add and Copy operation)
The package can be installed by adding jsonpatch
to your list of dependencies in mix.exs
:
def deps do
[
{:jsonpatch, "~> 1.0.1"}
]
end
The docs can be found at https://hexdocs.pm/jsonpatch.
iex> source = %{"name" => "Bob", "married" => false, "hobbies" => ["Sport", "Elixir", "Football"]}
iex> destination = %{"name" => "Bob", "married" => true, "hobbies" => ["Elixir!"], "age" => 33}
iex> Jsonpatch.diff(source, destination)
{:ok, [
%Jsonpatch.Operation.Add{path: "/age", value: 33},
%Jsonpatch.Operation.Replace{path: "/hobbies/0", value: "Elixir!"},
%Jsonpatch.Operation.Replace{path: "/married", value: true},
%Jsonpatch.Operation.Remove{path: "/hobbies/1"},
%Jsonpatch.Operation.Remove{path: "/hobbies/2"}
]}
Map a JSON patch struct to a regular map.
iex> add_patch_map = %Jsonpatch.Operation.Add{path: "/name", value: "Alice"}
iex> Jsonpatch.Mapper.to_map(add_patch_map)
%{op: "add", path: "/name", value: "Alice"}
Map a regular map to a JSON patch struct.
iex> add_patch_map = %{"op" => "add", "path" => "/name", "value" => "Alice"}
iex> Jsonpatch.Mapper.from_map(add_patch_map)
%Jsonpatch.Operation.Add{path: "/name", value: "Alice"}
iex> patch = [
%Jsonpatch.Operation.Add{path: "/age", value: 33},
%Jsonpatch.Operation.Replace{path: "/hobbies/0", value: "Elixir!"},
%Jsonpatch.Operation.Replace{path: "/married", value: true},
%Jsonpatch.Operation.Remove{path: "/hobbies/1"},
%Jsonpatch.Operation.Remove{path: "/hobbies/2"}
]
iex> target = %{"name" => "Bob", "married" => false, "hobbies" => ["Sport", "Elixir", "Football"]}
iex> Jsonpatch.apply_patch(patch, target)
{:ok, %{"name" => "Bob", "married" => true, "hobbies" => ["Elixir!"], "age" => 33}}
With Mix.install
small scripts can be written to create JSON patches.
Mix.install([:jsonpatch, :poison])
source =
File.read!("foo.json")
|> Poison.Parser.parse!(%{})
destination =
File.read!("bar.json")
|> Poison.Parser.parse!(%{})
patch =
source
|> Jsonpatch.diff(destination)
|> Jsonpatch.Mapper.to_map()
IO.inspect(patch, label: :patch)