guide/json-diff.md

Как сравнивать JSON — сортировка ключей и нормализация

Как убрать ложные различия из-за порядка ключей, отступов и записи чисел при сравнении двух JSON, а также о порядке массивов, больших целых числах и отличии от JSON Patch.

Обновлено: 2026-09-23

Сравнивать данные в JSON — ответы API, файлы настроек, файлы переводов — приходится часто. Но если сравнить два JSON как обычный текст, нередко получается множество различий при одинаковых данных. В этой статье объясняется, почему так происходит и как это исправить.

Откуда берутся ложные различия

Стандарт JSON (RFC 8259) определяет объект как «неупорядоченный набор пар имя/значение». То есть {"a":1,"b":2} и {"b":2,"a":1} означают одни и те же данные. Но в тексте порядок строк разный, и diff считает это различием. Кроме того, независимо от данных возникают такие различия:

Решение: разобрать и записать в одинаковом виде

Самый надёжный способ — разобрать оба JSON в данные и снова сериализовать их по одним и тем же правилам.

  1. Разберите оба текста как JSON. Если есть синтаксические ошибки, сначала исправьте их.
  2. Рекурсивно отсортируйте ключи всех объектов.
  3. Запишите результат с одинаковым отступом (например, 2 пробела).
  4. Сравните полученный текст построчно.

Например, в двух JSON ниже различается порядок ключей и порядок элементов массива.

{"name":"kim","age":30,"tags":["a","b"]}
{"age":30,"name":"kim","tags":["b","a"]}

После сортировки и перезаписи различие в порядке ключей исчезает, и остаётся только настоящее различие — порядок в массиве.

@@ -2,7 +2,7 @@   "age": 30,   "name": "kim",   "tags": [-    "a",-    "b"+    "b",+    "a"   ] }

Массивы не сортируются

В отличие от объектов, у массивов порядок имеет значение. ["a","b"] и ["b","a"] — разные данные. Поэтому при нормализации массивы, как правило, не сортируют. Однако если порядок в массиве для задачи не важен, как у списка тегов, результат будет проще читать, если отсортировать его вручную перед сравнением. Что правильно, зависит от смысла данных.

Что меняет разбор

У способа «разобрать и записать заново» есть побочные эффекты, о которых стоит знать.

Как это сделать в командной строке

Если установлен jq, опция -S (--sort-keys) выводит JSON с отсортированными ключами.

jq -S . before.json > a.json
jq -S . after.json  > b.json
diff -u a.json b.json

Отличие от JSON Patch

Результат diff — построчный список изменений для чтения человеком. JSON Patch (RFC 6902) — стандарт, описывающий изменения путями в структуре JSON, например {"op":"replace","path":"/age","value":31}, а JSON Merge Patch (RFC 7396) — способ наложить на оригинал JSON, содержащий только изменённые части. Для обмена изменениями между программами подходят эти стандарты, а для проверки человеком — текстовый diff после сортировки.

Попробуйте в этом инструменте

Если включить в сравнении текстов опцию Сортировать ключи JSON, обе стороны будут разобраны, ключи отсортированы, текст переписан с отступом в 2 пробела, и только потом выполнится сравнение. Порядок элементов массивов не меняется, а при ошибке разбора инструмент сообщит, на какой стороне и на каком символе она произошла. Можно перетащить сразу два файла .json. Как читать результат в виде patch, описано в статье Как читать unified diff.

Перейти к сравнению текстов