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 }
]
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
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
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
}
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);
Now student behaves like a normal Java object:
student.getName();
But it also supports JSON-semantic APIs:
student.getInteger("age");
student.getIntegerByPath("$.scores.math");
Defining a JSON Patch
JsonPatch patch = JsonPatch.fromJson("""
[
{ "op": "replace", "path": "/name", "value": "Alice Zhang" },
{ "op": "add", "path": "/scores/physics", "value": 91 }
]
""");
Applying the Patch
patch.apply(student);
After applying the patch:
student.getName(); // Alice Zhang
student.getIntegerByPath("$.scores.physics"); // 91
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 }
]
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:
Top comments (0)