JSON Pointer (RFC 6901)
A JSON Pointer is a string that identifies a specific value within a JSON document. It always starts with / and uses / to separate path segments:
1{2 "users": [3 { "name": "Alice", "age": 30 },4 { "name": "Bob", "age": 25 }5 ],6 "meta": {7 "version": "2.1"8 }9}| Pointer | Resolved Value |
|---|---|
| "" (empty string) | The entire document (root) |
| "/users" | The users array |
| "/users/0" | { "name": "Alice", "age": 30 } |
| "/users/0/name" | "Alice" |
| "/users/1/age" | 25 |
| "/meta/version" | "2.1" |
Escaping Special Characters
Two characters need escaping in JSON Pointer:
| Character | Escape Sequence | Example Key → Pointer |
|---|---|---|
| ~ (tilde) | ~0 | "a~b" → "/a~0b" |
| / (slash) | ~1 | "a/b" → "/a~1b" |
Tip
~1 with /, then ~0 with ~.JSON Patch (RFC 6902)
A JSON Patch document is an array of operations. Each operation has an op and a path (JSON Pointer):
All Six Operations — With Examples
1. add
Inserts a value at the target path. If the path points to an array index, the value is inserted before that index.
1{ "op": "add", "path": "/users/0/email", "value": "[email protected]" }1{ "op": "add", "path": "/users/1", "value": { "name": "Charlie", "age": 28 } }Note
/array/- to append to the end of an array (the - character means “after the last element”).2. remove
Deletes the value at the target path. The path must exist or the operation fails.
1{ "op": "remove", "path": "/users/1" }3. replace
Replaces the value at the target path. Equivalent to a remove followed by an add at the same path.
1{ "op": "replace", "path": "/users/0/age", "value": 31 }4. move
Removes the value at from and adds it at path.
1{ "op": "move", "from": "/users/0/name", "path": "/users/0/displayName" }5. copy
Copies the value at from to path (without removing the original).
1{ "op": "copy", "from": "/users/0/name", "path": "/meta/lastUser" }6. test
Asserts that the value at path equals value. If the assertion fails, the entire patch is rejected. Use this for optimistic concurrency control:
1[2 { "op": "test", "path": "/meta/version", "value": "2.1" },3 { "op": "replace", "path": "/meta/version", "value": "2.2" }4]If /meta/version is not "2.1", neither operation executes.
Complete Patch Example
1{2 "title": "My Post",3 "tags": ["json", "api"],4 "published": false,5 "views": 06}1[2 { "op": "replace", "path": "/title", "value": "My Updated Post" },3 { "op": "add", "path": "/tags/-", "value": "tutorial" },4 { "op": "remove", "path": "/views" },5 { "op": "replace", "path": "/published", "value": true },6 { "op": "add", "path": "/updatedAt", "value": "2026-04-02T10:00:00Z" }7]1{2 "title": "My Updated Post",3 "tags": ["json", "api", "tutorial"],4 "published": true,5 "updatedAt": "2026-04-02T10:00:00Z"6}JSON Merge Patch (RFC 7396)
JSON Merge Patch is a simpler alternative. Instead of an array of operations, you send a partial document. Present keys are updated, keys set to null are deleted, missing keys are unchanged.
1{2 "title": "My Updated Post",3 "views": null,4 "published": true5}| Feature | JSON Patch (RFC 6902) | JSON Merge Patch (RFC 7396) |
|---|---|---|
| Format | Array of operations | Partial document |
| Set a value to null | Yes — use replace | No — null means "delete" |
| Array manipulation | Precise index control | Replace entire array only |
| Atomicity | Built-in with "test" | No built-in assertion |
| Content-Type | application/json-patch+json | application/merge-patch+json |
| Complexity | Higher | Much simpler |
Tip
Using JSON Patch in APIs
1import express from 'express';2import { applyPatch, validate } from 'fast-json-patch';34const app = express();5app.use(express.json());67app.patch('/api/posts/:id', async (req, res) => {8 const post = await db.posts.findById(req.params.id);9 if (!post) return res.status(404).json({ error: 'Not found' });1011 const errors = validate(req.body, post);12 if (errors) return res.status(400).json({ error: errors.message });1314 const { newDocument } = applyPatch(post, req.body, true, false);15 await db.posts.update(req.params.id, newDocument);1617 res.json(newDocument);18});Try It — Validate a Patch Document
Try It Yourself
A valid JSON Patch document — each operation needs op and path