Back to HTTP Methods
Q2Question 2 of 5

Explain the PATCH method and JSON Patch (RFC 6902)

Key Concepts
  • PATCH applies a partial modification to a resource, sending only the changes rather than the entire representation.
  • JSON Patch (RFC 6902) uses Content-Type application/json-patch+json and expresses changes as an ordered array of operation objects.
  • The six operations are add, remove, replace, move, copy, and test, each targeting a field by JSON Pointer path.
  • Operations are applied in order and atomically: if any fails, the entire patch is rejected and the resource is unchanged.
  • The test operation enables optimistic concurrency by asserting a value before allowing changes.
  • JSON Merge Patch (RFC 7396) is a simpler alternative where present fields are set and explicit null deletes a field.

Definition

PATCH applies a partial modification to a resource, and JSON Patch (RFC 6902) is a standard format for expressing those changes as an ordered array of operations like add, remove, replace, move, copy, and test.
  • PATCH – an HTTP method that applies a partial modification to a resource, sending only the changes rather than the entire representation.
  • JSON Patch (RFC 6902) – a standard JSON format using Content-Type: application/json-patch+json that expresses changes as an ordered array of operation objects.
  • Operations – each object has an op (add, remove, replace, move, copy, test), a path in JSON Pointer syntax, and optionally a value.
  • Atomic – all operations apply in order and atomically; if any fails, the entire patch is rejected and the resource is unchanged.
  • Test operation – asserts a value at a path matches an expected value, enabling optimistic concurrency without server-side locking.
  • JSON Merge Patch (RFC 7396) – a simpler alternative where a partial object is sent; present fields are set and explicit null deletes a field.

Imagine Priya's account record at National Bank of India is a paper form. Instead of handing in a whole new form, she gives the clerk a short list of precise instructions: replace the phone number at line 3 with this new one, remove the old address at line 5, add a new nominee at line 8. JSON Patch is exactly that list of instructions. Each instruction names the operation, points to the exact field, and gives the value. The clerk follows them in order, and there is even a test instruction that says "only proceed if line 3 currently equals this expected value."

Understanding the Concepts

What is the PATCH method?

PATCH is an HTTP method that applies a partial modification to a resource. Unlike PUT, which replaces the entire resource, PATCH sends only the changes. The method itself does not dictate the body format: it just means "partial update." Two standard formats fill that gap: JSON Merge Patch (RFC 7396) and JSON Patch (RFC 6902).

JAVA
// PATCH sends only the fields to change.
// PATCH /api/v1/beneficiaries/BEN-77
// Content-Type: application/merge-patch+json
// {"nickname": "Landlord"}
// → Only nickname changes; accountNumber, ifsc, etc. remain untouched.

What is JSON Patch (RFC 6902)?

JSON Patch is a standard format defined in RFC 6902 for expressing changes to a JSON document as an ordered array of operations. The content type is application/json-patch+json. Each operation object has an op field naming the operation, a path field in JSON Pointer syntax, and sometimes a value.

  • The six operations are:
  • add – adds a new member to an object or inserts into an array.
  • remove – deletes a field or array element.
  • replace – changes an existing value to a new one.
  • move – moves a value from one path to another.
  • copy – duplicates a value to another path.
  • test – asserts a value at a path equals an expected value; if not, the entire patch fails.
JAVA
// A JSON Patch document (Content-Type: application/json-patch+json)
// [
//   {"op": "test",    "path": "/nickname",  "value": "Rajesh"},
//   {"op": "replace", "path": "/nickname",  "value": "Landlord"},
//   {"op": "remove",  "path": "/ifsc"},
//   {"op": "add",     "path": "/nominees/-", "value": {"name": "Priya"}}
// ]

How does JSON Patch differ from JSON Merge Patch?

JSON Merge Patch (RFC 7396) is simpler: you send a partial JSON object where present fields are set and an explicit null deletes a field. JSON Patch (RFC 6902) is more expressive: it supports ordered operations, array manipulation, move, copy, and the test operation for optimistic concurrency.

| Feature | JSON Merge Patch (RFC 7396) | JSON Patch (RFC 6902) |
|---|---|---|
| Content-Type | application/merge-patch+json | application/json-patch+json |
| Format | Partial JSON object | Array of operation objects |
| Delete a field | Set field to null | {"op": "remove", "path": "/field"} |
| Array manipulation | Replace entire array | Insert, remove, move individual elements |
| Conditional update | Not supported | test operation |
| Ordering | No ordering of changes | Operations applied in order |
| Complexity | Simple | More expressive |

JAVA
// JSON Merge Patch: simple partial object.
// PATCH /api/v1/beneficiaries/BEN-77
// Content-Type: application/merge-patch+json
// {"nickname": "Landlord", "ifsc": null}
// → Sets nickname to "Landlord", deletes ifsc.

// JSON Patch: ordered operations with test.
// PATCH /api/v1/beneficiaries/BEN-77
// Content-Type: application/json-patch+json
// [
//   {"op": "test",    "path": "/nickname", "value": "Rajesh"},
//   {"op": "replace", "path": "/nickname", "value": "Landlord"},
//   {"op": "remove",  "path": "/ifsc"}
// ]

How do you apply JSON Patch in Java?

In Java you use the JSON-P (Jakarta JSON Processing) API. You parse the patch into a JsonPatch, parse the target resource into a JsonObject, and call patch.apply(target). The operations are applied in order and atomically.

JAVA
package com.bank.service;

import jakarta.json.*;
import java.io.StringReader;

public class BeneficiaryPatchService {

    public String applyPatch(String patchJson, String resourceJson) {
        JsonArray patchArray = Json.createReader(new StringReader(patchJson)).readArray();
        JsonPatch patch = Json.createPatchBuilder(patchArray).build();
        JsonObject target = Json.createReader(new StringReader(resourceJson)).readObject();
        JsonObject patched = patch.apply(target); // atomic: all or nothing
        return patched.toString();
    }
}

How does the test operation enable optimistic concurrency?

The test operation asserts that a value at a given path matches an expected value. If the assertion fails, the entire patch is rejected and the resource is unchanged. This gives optimistic concurrency without server-side locking: Priya includes a test that the nickname still equals "Rajesh," so her rename only happens if nobody changed it underneath her.

JAVA
// Test operation for optimistic concurrency:
// [
//   {"op": "test",    "path": "/version", "value": 7},
//   {"op": "replace", "path": "/nickname", "value": "Landlord"}
// ]
// If version is still 7, the replace proceeds.
// If someone bumped version to 8, the test fails → 409 Conflict, nothing changes.

What are the security concerns with JSON Patch?

JSON Patch is powerful but harder to validate and secure than a plain DTO, because the client can target arbitrary paths. You must restrict which paths are patchable so a client cannot replace /balance directly or modify /role to escalate privileges.

JAVA
package com.bank.service;

import java.util.Set;

public class PatchValidator {

    private static final Set<String> ALLOWED_PATHS = Set.of(
            "/nickname", "/phoneNumber", "/nominees/-");

    public void validate(String patchJson) {
        // Parse patch and check each operation's path against the whitelist.
        // Reject if any path is not in ALLOWED_PATHS.
        // This prevents clients from patching /balance or /role.
    }
}

When should you use JSON Patch vs JSON Merge Patch?

Use JSON Merge Patch for most internal APIs where partial updates are simple: set a few fields, maybe delete one with null. Use JSON Patch when you need ordered operations, array element manipulation, the test operation for optimistic concurrency, or move and copy operations. In banking, JSON Patch's test operation is valuable for safe concurrent profile edits.

JAVA
// Decision: which format to use?
// Simple field updates → JSON Merge Patch (simpler, less code)
// Array manipulation, conditional updates → JSON Patch (more expressive)
// Optimistic concurrency → JSON Patch test operation

What are common mistakes with PATCH?

A common mistake is treating PATCH as idempotent when it may not be. Another is not distinguishing between "field is null" and "field is absent" in a merge patch, which loses the ability to delete a field. A third is not validating paths in a JSON Patch, allowing clients to modify sensitive fields.

JAVA
// Wrong: no path validation – client can patch /balance.
@PatchMapping("/beneficiaries/{id}")
public Beneficiary patch(@PathVariable String id, @RequestBody String patchJson) {
    return patchService.apply(id, patchJson); // Any path accepted!
}

// Correct: validate paths before applying.
@PatchMapping("/beneficiaries/{id}")
public Beneficiary patch(@PathVariable String id, @RequestBody String patchJson) {
    patchValidator.validate(patchJson); // Rejects disallowed paths
    return patchService.apply(id, patchJson);
}

Visual Overview

DIAGRAM
┌──────────────────────────────────────────────────────┐
│               JSON Patch Application Flow              │
├──────────────────────────────────────────────────────┤
│                                                      │
│  Client sends PATCH request:                         │
│  Content-Type: application/json-patch+json           │
│  [                                                   │
│    {"op": "test",    "path": "/nickname", "value": "Rajesh"},│
│    {"op": "replace", "path": "/nickname", "value": "Landlord"},│
│    {"op": "remove",  "path": "/ifsc"}                │
│  ]                                                   │
│       │                                              │
│       ▼                                              │
│  Server validates paths against whitelist            │
│       │                                              │
│       ▼                                              │
│  Apply operations in order (atomic):                 │
│  ┌──────────────────────────────────────┐            │
│  │ 1. TEST: nickname == "Rajesh"?       │            │
│  │    Yes → continue                    │            │
│  │    No  → REJECT entire patch (409)   │            │
│  ├──────────────────────────────────────┤            │
│  │ 2. REPLACE: nickname ← "Landlord"   │            │
│  ├──────────────────────────────────────┤            │
│  │ 3. REMOVE: ifsc deleted             │            │
│  └──────────────────────────────────────┘            │
│       │                                              │
│       ▼                                              │
│  All succeeded → 200 OK + updated resource           │
│  Any failed    → 409/422, resource unchanged         │
└──────────────────────────────────────────────────────┘

Key Takeaway

PATCH means a partial update, but the HTTP method itself does not dictate the body format, so a standard is needed. JSON Patch, defined in RFC 6902, is the most expressive option. A JSON Patch body is an ordered array of operations, where each operation has an op such as add, remove, replace, move, copy, or test, a path in JSON Pointer syntax pointing at the exact field, and sometimes a value. The content type is application/json-patch+json.

What makes JSON Patch powerful is that it describes changes rather than a new state, and it applies the operations in order and atomically. If any operation fails, including a failing test operation, the entire patch is rejected and the resource is left unchanged. At National Bank of India this atomicity was essential: when Priya renamed her nickname, removed a wrong IFSC, and added a nominee in one request, all three had to apply together or none at all, because a half-updated profile is unacceptable in a bank.

The test operation is the feature worth highlighting most, because it gives optimistic concurrency without server-side locking. Priya includes a test that the nickname still equals "Rajesh," so her rename only happens if nobody changed it underneath her. If the value already changed, the test fails and the whole patch is rejected with a conflict, so she never silently overwrites someone else's change.

The simpler alternative is JSON Merge Patch from RFC 7396, where a present field is set and an explicit null deletes it. For most internal APIs that is enough. JSON Patch earns its complexity when you need ordered operations, array manipulation, or the conditional test for safe concurrent updates.

Remember one sentence: JSON Patch is an ordered, atomic array of operations that can test, add, remove, replace, move, and copy individual fields, giving you precise partial updates with built-in optimistic concurrency.

---

Share
Use ← → arrow keys to navigate