DEV Community

Yu Han
Yu Han

Posted on

JSON Patch in Java — Without Converting Everything to JsonNode

Partial updates are everywhere.

Modern APIs frequently support HTTP PATCH, and JSON Patch (defined in RFC 6902) has become a standard way to describe structural changes to JSON documents.

A typical patch looks like this:

[
  { "op": "replace", "path": "/name", "value": "Alice Zhang" },
  { "op": "add", "path": "/scores/physics", "value": 91 }
]
Enter fullscreen mode Exit fullscreen mode

Conceptually, it’s simple:

  • replace a value
  • add a value
  • remove something
  • move something

JSON Patch is elegant.

But when using it in Java, things often become… slightly less elegant.

The Usual Java Workflow

Most JSON Patch libraries operate on JSON tree models.

Which means your code typically looks like this:

POJO
 ↓
JsonNode
 ↓
apply patch
 ↓
JsonNode
 ↓
POJO
Enter fullscreen mode Exit fullscreen mode

In practice this means:

  • converting your objects into JSON trees
  • applying the patch
  • converting everything back

This works, but it introduces extra layers and conversions that aren't really related to the domain model.

A Different Approach

Instead of operating on a JSON tree, SJF4J applies patch operations directly to the object graph.

The workflow becomes:

Object Graph
    ↓
apply patch
    ↓
Object Graph
Enter fullscreen mode Exit fullscreen mode

No intermediate JSON tree.

This works because SJF4J uses a unified structural model called OBNT (Object-Based Node Tree), where native Java objects themselves act as the JSON structure.

Example Model

Let’s start with a simple model:

public class Student extends JsonObject {
    private String name;
    private Map<String, Integer> scores;
    private List<Student> friends;
    // Getters and setters
}
Enter fullscreen mode Exit fullscreen mode

This class extends JsonObject, which means it behaves both as:

  • a typed Java object
  • a dynamic JSON structure

Parsing JSON

String json = """
{
  "name": "Alice",
  "scores": {
    "math": 59
  }
}
""";

Student student = Sjf4j.fromJson(json, Student.class);
Enter fullscreen mode Exit fullscreen mode

Now student behaves like a normal Java object:

student.getName();
Enter fullscreen mode Exit fullscreen mode

But it also supports JSON-semantic APIs:

student.getInteger("age");
student.getIntegerByPath("$.scores.math");
Enter fullscreen mode Exit fullscreen mode

Defining a JSON Patch

JsonPatch patch = JsonPatch.fromJson("""
[
  { "op": "replace", "path": "/name", "value": "Alice Zhang" },
  { "op": "add", "path": "/scores/physics", "value": 91 }
]
""");
Enter fullscreen mode Exit fullscreen mode

Applying the Patch

patch.apply(student);
Enter fullscreen mode Exit fullscreen mode

After applying the patch:

student.getName(); // Alice Zhang

student.getIntegerByPath("$.scores.physics"); // 91
Enter fullscreen mode Exit fullscreen mode

The object graph is updated in place.

Nested Updates Work Naturally

JSON Patch paths work naturally with nested structures.

Example:

[
  { "op": "add", "path": "/friends/0/scores/music", "value": 100 }
]
Enter fullscreen mode Exit fullscreen mode

Applying this patch will automatically update nested objects.

Comparing Approaches

When patches operate directly on object graphs:

  • fewer conversions happen
  • less intermediate structure is required
  • the code stays closer to the domain model
  • higher performance

Why JSON Patch Fits This Model

JSON Patch is fundamentally a structural transformation language.

It describes changes in terms of:

  • paths
  • operations
  • values

That makes it a natural fit for a structural object model rather than a serialization layer.

Final Thoughts

JSON Patch is a powerful standard for partial updates.

But the developer experience depends heavily on how it's implemented.

When patch operations work directly on Java object graphs instead of JSON trees, they become significantly simpler to use.


Project:

https://github.com/sjf4j-projects/sjf4j
https://sjf4j.org

Top comments (0)