JSON Patch
JSON Patch — формат для описания изменений в JSON-документе. Вместо отправки документа для обновления, отправляется набор операций («патч»), которые нужно применить.
Экономит трафик, делает изменения предсказуемыми и атомарными.
Описан в стандарте RFC 6902
Примеры применения
- в RESTful API для частичного обновления ресурсов (PATCH-запросы),
- для синхронизации состояния между клиентами
- где важно версионирование
- в event-sourcing как событие
Пример
Исходно:
{ "user": "Иван", "age": 30 }
Патч (набор операций):
[
{ "op": "replace", "path": "/age", "value": 31 },
{ "op": "add", "path": "/city", "value": "Москва" }
]
Результат:
{ "user": "Иван", "age": 31, "city": "Москва" }
Особенности
Строгий формат операций
Операция (op) | Обязательные поля | Описание |
|---|---|---|
add | path, value | Добавляет значение по указанному пути. Если путь указывает на существующий ключ объекта — перезаписывает его. Если на индекс массива — вставляет элемент, сдвигая существующие вправо. Использование /- добавляет в конец массива. |
remove | path | Удаляет значение по указанному пути. Для массива удаляет элемент, сдвигая остальные влево. |
replace | path, value | Короткий синтаксис для remove + add по тому же пути. Полностью заменяет значение по указанному пути на новое. Путь должен существовать. |
move | from, path | Перемещает значение из пути from в путь path. Эквивалентно операции remove по from, а затем add по path с тем же значением, но выполняется атомарно. |
copy | from, path | Копирует значение из пути from в путь path. Исходное значение остается на месте. Эквивалентно операции add по path со значением, взятым из from. |
test | path, value | Проверяет, что значение по указанному path в текущем документе совпадает с предоставленным value. Если не совпадает — патч не применяется (вся транзакция откатывается). |
Расширять этот набор другими операциями нельзя, если нужно сохранить совместимость с системами, реализующими RFC 6902.
Применяется атомарно
Если любая операция в массиве завершается ошибкой (например, путь не найден для remove, или операция test возвращает false), весь патч должен быть откачен, и документ остается без изменений.
Это гарантирует целостность.
Операции применяются последовательно
Последующие могут зависеть от результата предыдущих.
Пример: чтобы переместить (move) данные из /a в /b, сначала убедиться, что /b не существует, или удалить его в предыдущей операции.
Важно: для безопасности нужно валидировать входящие патчи (особенно пути), чтобы избежать инъекций или изменения системных данных.
JSON Patch vs JSON Merge Patch
JSON Merge Patch (RFC 7396)
Простой формат для слияния (merge) JSON-документов. Отправляется фрагмент, который нужно "наложить" на целевой документ:
- значения заменяются
nullозначает "удалить поле"- отправляются только изменяемы е поля
Пример:
// Исходный: {"a": "b", "c": {"d": "e"}}
// Патч: {"a": "z", "c": {"f": "g"}, "h": null}
// Результат: {"a": "z", "c": {"d": "e", "f": "g"}}
// (h удалён, d остался)