Сравнить два JSON
Кладёте два ответа API рядом — получаете список различий с полным путём до каждого поля: data.items[0].price. Порядок ключей в объекте значения не имеет, так что перестановка полей за различие не считается; для массивов порядок можно отключить отдельно.
| Путь | Что произошло | Было | Стало |
|---|
Виды различий
| Метка | Что означает |
|---|---|
| появилось | Поля не было в левом JSON, в правом оно есть |
| пропало | Поле было слева, справа его нет |
| изменилось | Поле на месте, значение другое |
| сменился тип | Было число, стала строка; был объект, пришёл null |
Почему построчный diff тут не работает
Кладёте два ответа сервера рядом — получаете список различий с полным путём до каждого поля вида data.items[0].price. Это удобнее построчного сравнения текстов: в JSON порядок ключей не значим, и обычный текстовый диff показал бы отличие там, где данные совпадают.
Различия делятся на три вида: поле появилось, поле исчезло, значение изменилось. Для изменённых показываются оба значения рядом. Вложенность раскрывается полностью, поэтому отличие в глубоко спрятанном поле не приходится искать глазами.
Массивы сравниваются по позициям. Если элемент вставили в середину, все последующие сместятся и покажутся изменёнными — это ожидаемое поведение, и обходится оно сортировкой обоих массивов по ключевому полю перед сравнением.

| Тип различия | Что показывает |
|---|---|
| Добавлено | Поле есть только во втором |
| Удалено | Поле есть только в первом |
| Изменено | Оба значения рядом |
| Совпадает | Скрывается, чтобы не мешать |
От программы diff до JSON Patch
Задачу сравнения двух последовательностей формализовали в шестидесятые и семидесятые. Алгоритм поиска наибольшей общей подпоследовательности лежит в основе программы diff, которая появилась в Unix в 1974 году. В 1986 году Юджин Майерс опубликовал алгоритм, который до сих пор работает в системах контроля версий.
Для древовидных данных построчное сравнение работает плохо. Одно и то же содержимое можно записать с разными отступами и в разном порядке ключей, и текстовый diff покажет отличия там, где их нет. Поэтому появились алгоритмы структурного сравнения, работающие с деревом вместо строк.
Формат записи различий тоже стандартизовали: документ RFC 6902 описывает JSON Patch — список операций добавления, удаления и замены с путями в формате JSON Pointer. Такой патч можно применить к документу программно, и это удобно для синхронизации данных между системами. Похожая задача решается и при синхронизации: клиент отправляет на сервер только список изменений, и это заметно экономит трафик на больших структурах, а заодно даёт понятную историю правок вместо череды полных копий документа.
Как готовить данные к сравнению
Вставьте оба ответа и посмотрите список. Первым делом обращайте внимание на исчезнувшие поля: чаще всего именно они ломают потребителя данных, потому что код обращается к тому, чего больше нет.
Перед сравнением ответов от разных сред уберите заведомо изменчивые поля — метки времени, идентификаторы запроса, подписи. Иначе список различий утонет в шуме, и настоящие расхождения в нём потеряются.
Для массивов объектов сортируйте оба по устойчивому ключу: тогда сравнение пойдёт по существу, минуя позиционные сдвиги. Привести оба документа к одинаковому виду перед сравнением поможет JSON-форматтер.
Сохраняйте эталонные ответы рядом с тестами и обновляйте их осознанно, каждый раз проверяя, что изменение в чужом интерфейсе действительно заявлено, а молчаливых правок там не было. Сравнение свежего ответа с записанным раньше ловит незаявленные изменения в чужом интерфейсе намного быстрее, чем это делают жалобы потребителей данных на сломавшуюся выгрузку.
Различие в типе значения заметить труднее всего. Строка «10» и число 10 выглядят одинаково в выводе, но ведут себя по-разному при сортировке и сравнении. Смотрите на кавычки в списке различий: смена типа поля ломает потребителя данных не реже, чем исчезновение самого поля, а замечают её обычно гораздо позже.
| Программа diff | Unix, 1974 |
| Алгоритм Майерса | 1986 |
| Основа | наибольшая общая подпоследовательность |
| Стандарт записи различий | RFC 6902 |
| Формат пути | JSON Pointer |
| Порядок ключей | не значим |
| Массивы | сравниваются по позициям |
| Что убрать перед сверкой | метки времени и идентификаторы |
Как пользоваться
Служебные поля вроде updatedAt, requestId и подписи выбрасываются из сравнения списком исключений — иначе каждый ответ отличается от предыдущего и смотреть не на что. Различия разложены по видам: поле появилось, поле пропало, значение изменилось, поменялся тип. Разбор идёт в браузере, ответы никуда не отправляются.
- Слева тот, что был, справа тот, что стал. Оба поля проверяются на разбор сразу, ошибка показывается под полем.
- Порядок элементов массива, регистр строк и числа-строки можно приравнять. По умолчанию сравнение строгое.
- Впишите их имена через запятую: updatedAt, requestId, signature. Поле с таким именем выпадает из сравнения на любой глубине.
- Каждая строка — один путь до поля, вид изменения и значения с обеих сторон.
Частые вопросы
Чем это отличается от сравнения двух текстов?
Текстовое сравнение работает построчно и считает различием любую перестановку и любой лишний пробел. JSON сравнивается по структуре: важны имена полей и значения, а порядок ключей и форматирование роли не играют. Поэтому два одинаковых по смыслу ответа, записанных по-разному, здесь окажутся одинаковыми.
Почему порядок в массиве по умолчанию важен?
В массиве порядок несёт смысл: список товаров в выдаче, шаги сценария, элементы меню. Если для вашей задачи это набор без порядка, включите отдельную настройку — тогда элементы будут сопоставляться по содержимому, а перестановка перестанет считаться различием.
Что означает «поменялся тип»?
Слева и справа одно и то же поле, но разного вида: было число 10, стала строка «10», или вместо объекта пришёл null. Такие расхождения выносятся отдельно, потому что они чаще всего и ломают разбор на стороне получателя, даже когда значение выглядит тем же самым.
Зачем исключать поля из сравнения?
Ответы API почти всегда содержат метки времени, идентификаторы запроса и подписи. Они меняются при каждом обращении, и без исключений список различий состоит из них одних. Убрав их, вы видите то, что действительно изменилось в данных.
Есть ли предел размера?
Около двух мегабайт на каждое поле и десять тысяч различий в выводе. На большем объёме вкладка начнёт подвисать, поэтому лишнее лучше отрезать заранее.
Инструмент показывает, какой JSON правильный?
Нет, он показывает разницу. Какая из сторон верная, знает только тот, кто ставил задачу: иногда изменение и есть ожидаемый результат, иногда оно и есть поломка.
Куда уходит вставленный текст?
Нет. Разбор и сравнение идут кодом страницы, сетевых запросов при работе не происходит.
Спросите нейросети об инструменте
Больше возможностей: Нейросеть для кода, написать, найти ошибку, объяснить.
Похожие инструменты
Разбирает JSON с отступами и в одну строку, показывает дерево с путями к узлам и объясняет ошибку по-русски: где висячая запятая, где кавычки из Word, где комментарий.
ОткрытьШифр ВиженераШифрование и расшифровка по ключевому слову, а также шифр Цезаря со сдвигом и Атбаш, русский и латинский алфавиты, таблица Виженера.
ОткрытьКартинка в Base64Изображение в data URI для HTML и CSS и обратно: размер до и после, готовые фрагменты img и background, предпросмотр из строки.
ОткрытьСканер QR-кодаСчитывает QR-код и штрихкод камерой или с картинки прямо в браузере: ссылка, Wi-Fi, визитка, телефон и номер товара разбираются по полям.
ОткрытьJWT-декодерРазбор токена JWT: заголовок, полезная нагрузка с расшифровкой стандартных полей, сроки выдачи и истечения в датах, проверка структуры. Без отправки на сервер.
ОткрытьHTML-сущностиКодирование спецсимволов в &, < и числовые сущности и обратное декодирование, таблица частых сущностей с кодами.
ОткрытьЕщё инструменты для кода и данных
Base64 и URL, форматтер и сравнение JSON, хеши, регулярные выражения, cron, подсети, UUID, QR-код и Unix-время — в разделе 42 инструмента.

