Сравните два JSON-документа по структуре, а не по строкам. Сообщает о добавленных, удалённых и изменённых путях с опцией игнорирования порядка массива. Работает полностью в браузере.
Сравнивайте по структуре, а не по строкам. Вставьте два документа и получите отчёт по путям о том, что добавлено, удалено или изменено. Поскольку сравнение обходит разобранные значения, переформатирование или перестановка ключей не считается различием.
–
Различия
Почему текстовый diff — неподходящий инструмент для JSON
Строчные diff видят форматирование, а не смысл
Стандартный построчный diff трактует JSON как прозу. Переотбейте файл с двух пробелов на четыре — и каждая строка помечается как изменённая. Переместите ключ из начала объекта в конец — и вы получите одно удаление плюс одну вставку, хотя разобранное значение точно такое же. Сверните длинный массив в одну строку — и весь блок загорается.
Структурный diff сначала разбирает обе стороны, а затем обходит полученные значения. Форматирование, порядок ключей и пробелы исчезают к моменту начала сравнения, поэтому сообщить можно только о подлинных различиях в данных. Именно поэтому вывод достаточно короток, чтобы его можно было прочитать.
Пути, а не номера строк
Каждое различие здесь сообщается относительно пути вроде user.roles[2] или meta.updated. Путь переживает правки в другом месте документа, чего не делает номер строки, поэтому вы можете вставить тот же отчёт в тикет или ревью кода, и он всё равно будет указывать на нужное место неделю спустя.
Три операции отображаются на то, что на самом деле может произойти с деревом. Ключ, присутствующий слева, но не справа, — это удаление; обратное — добавление; ключ, присутствующий с обеих сторон с разным значением, — изменение. Изменения типа — поле, которое раньше было числом 1, а теперь строкой "1", — тоже сообщаются как изменения, и на них стоит обратить внимание, поскольку это частый источник последующих багов, которые не ловит ни одна проверка схемы.
Массивы и вопрос порядка
Массивы — там, где структурное сравнение становится категоричным. По умолчанию сравнение позиционное: индекс 0 слева сравнивается с индексом 0 справа. Это верно для упорядоченных данных вроде последовательности шагов, но даёт вводящий в заблуждение результат для списка, который на самом деле является множеством, — переставьте элементы, и каждая позиция кажется изменённой.
Опция игнорирования порядка массива канонизирует обе стороны, предварительно глубоко отсортировав массивы, поэтому переставленный список сравнивается как равный. Используйте её для списков тегов, множеств прав доступа и результатов запросов без гарантированного порядка. Отключайте, когда позиция элемента несёт смысл, поскольку при включении реальный баг перестановки становится невидимым.
FAQ
Чем это отличается от обычного текстового diff?
Текстовый diff сравнивает строки, поэтому переотбивка или перестановка ключей считается изменением. Этот инструмент сначала разбирает обе стороны, поэтому сообщается только о реальных различиях в данных.
Что означают символы +, - и ~?
Плюс — путь, присутствующий только в изменённом документе, минус — присутствующий только в исходном, тильда — путь, присутствующий в обоих с разным значением.
Почему переставленный массив сообщается как изменённый?
По умолчанию массивы сравниваются позиционно, что верно для упорядоченных данных. Включите игнорирование порядка массива, чтобы сравнивать их как неупорядоченные множества.
Имеет ли значение порядок ключей в объекте?
Нет. Объекты сравниваются по ключам, поэтому перемещение поля внутри объекта никогда не даёт различия. Порядок чувствителен только к позициям элементов массива.
Флагается ли число, ставшее строкой?
Да. Изменение типа сообщается как изменение намеренно: 1 и "1" ведут себя совершенно по-разному дальше по цепочке, и это несоответствие легко упустить иначе.
Отправляются ли мои документы на сервер?
Нет. Обе стороны разбираются и сравниваются в вашем браузере, поэтому ничего не загружается, не логируется и не сохраняется.