java-json-tools / json-patch

An RFC 6902 (JSON Patch) and reverse, plus RFC 7386 (JSON Merge Patch), implementation in Java using Jackson (2.2.x)
Other
633 stars 184 forks source link

Common interface for Patches #26

Open xelamitchell opened 9 years ago

xelamitchell commented 9 years ago

In my API I wish to support both "application/json-patch" and "application/merge-patch" for deeply related and large entities. An example in a Spring Controller:

 @RequestMapping(method = RequestMethod.PATCH, value = "/configurations/{id}", consumes = "application/merge-patch+json")
 public Configuration merge(@PathVariable Long id, @RequestBody ObjectNode request) {
   // Creates a JsonMergePatch from the ObjectNode and calls:
    return apply(id, mergePatch);
}

@RequestMapping(method = RequestMethod.PATCH, value = "/configurations/{id}", consumes = "application/json-patch+json")
public Configuration patch(@PathVariable Long id, @RequestBody ArrayNode request) {
    // Creates a JsonPatch from the ArrayNode and calls:
    return apply(id, jsonPatch);
}

private Configuration apply(Long id, Patch patch) {
    // Before Apply: Retrieves configuration from database using id, transforms it into a JsonNode
    JsonNode patchedNode = patch.apply(configurationNode);
    // After Apply: Transforms the patched node into a Configuration and saves to database.
    return patchedConfiguration;
}

In this case, the actions before and after patch application are the same independent of which patch I am applying and the apply method shouldn't really care which patch it is applying as long as it is a valid patch for JSON.

daveclayton commented 8 years ago

Hi @xelamitchell can you please clarify what you require in terms of changes to the json-patch libraries?

Thanks

xelamitchell commented 8 years ago

Hey there @daveclayton. I was just looking for JsonPatch and JsonMergePatch classes to implement an interface of the type:

public interface Patch {

    JsonNode apply(JsonNode node) throws JsonPatchException;

}

This way, independent of the operation type, a Provider can give me the appropriate Patch object (JsonPatch or JsonMergePatch) and the patch operation itself can be used transparently when validation of message happens in one level (Controller/Provider) and actual update (call to method apply(JsonNode)) happens in another (Service).

Many thanks

daveclayton commented 8 years ago

Hi

If I understand correctly, this is about pulling the apply method into an interface so that we can code to the behaviour instead of to the implementation (e.g. for IoC or Strategy, etc). Is that right?

There has been another question posted about splitting out interfaces and common objects into an API, so perhaps this should be tagged to that discussion so that we get the best solution overall.

What do you think?

xelamitchell commented 8 years ago

Yes, isolating the apply method in an interface for dependency injection is the intent.

It certainly looks to me as though such an interface would be an important aspect for an API.

zozoit commented 5 years ago

Hello,

Stumbled on the same issue than xelamitchell. A simple interface would be really useful to avoid duplication of code when one needs to provide both patch services.