Skip to content

Ability to generate diff as merge patch #77

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
dcokan opened this issue Jul 1, 2020 · 1 comment
Open

Ability to generate diff as merge patch #77

dcokan opened this issue Jul 1, 2020 · 1 comment

Comments

@dcokan
Copy link

dcokan commented Jul 1, 2020

Hi guys

I want to store a diffs between versions of a JSON. I can do it using collecting a diffs (RFC-6902). However with multiple changes I need to store big list of operations to be later applied. Since the library allows to apply merge patch to a JSON (RFC-7386) I think it would be very useful to be able to produce such merge patch having two JSONs. Is there a reason why it's not supported? Is it planned?

Thanks in advance

@torshid
Copy link

torshid commented Dec 28, 2020

I was wondering the same thing. In my client application, I call a patch endpoint which expects a merge patch. I would like to generate this patch given the original data and the modified one (two json nodes). The API then applies the patch and persists the updated data.
The problem is that there is no way to generate this patch, although we can apply it if we previously created it in some way.

I wrote a method as follows, it may be useful for some (not sure if it complies completely to RFC-7386):

  public static ObjectNode diff(ObjectMapper mapper, ObjectNode original, ObjectNode modified) {

    ObjectNode result = mapper.createObjectNode();

    Iterator<String> iterator = modified.fieldNames();

    while (iterator.hasNext()) {

      String fieldName = iterator.next();

      JsonNode originalFieldNode = original.get(fieldName);
      JsonNode modifiedFieldNode = modified.get(fieldName);

      if (modifiedFieldNode.equals(originalFieldNode)) {
        continue;
      }

      if (!originalFieldNode.isNull() && modifiedFieldNode.isObject()) {
        result.set(fieldName, diff(mapper, originalFieldNode, modifiedFieldNode));
      } else {
        result.set(fieldName, modifiedFieldNode);
      }

    }

    return result;

  }

You may use it like that:

final JsonMergePatch patch =  JsonMergePatch.fromJson(diff(...));
final JsonNode patched = patch.apply(input);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants