テキストとしてJSONを差分するのをやめるように教えてくれたバグが、週末のほとんどを費やしました 私が実行したLaravel SaaSの支払いWebフックが、プロバイダー" non-breaking" APIアップデートの後、静かに失敗し始めました - 彼らの言葉、変更ログから更新前のペイロードをログから引き出し、新鮮なものをつかみ、両方を通常のテキスト差分に投げ込みました すべての行が点灯しました プロバイダーはシリアライザーを切り替えたため、すべてのキーをアルファベット順に並べ替え、インデントを4 つのスペースから2 つのスペースに変更しました 600 行が変更され、そのどこかで、実際の違いが1 つ見つかる前に、その差分を上から下に2 回読みました: amount 番号から変わった 1099 文字列に "1099"。 画面上の同じ文字。 別のタイプ。 私たちの厳密な比較ではそれが拒否され、キューが地面に再試行され、差分テキストは 599 の化粧品の下に意味のある変更を埋めていました。
That' s the fundamental problem: JSONはデータ形式ですが、テキスト差分では散文として扱われます。 key order, whitespace, indentation, trailing newlines - none of it means anything to a JSON parser, and all of it shows up as changes in the line-based comparision.基本的な問題: JSONは、キーの順序、空白、インデント、末尾の改行 - どれもJSONパーサーには意味がなく、そのすべてが行ベースの比較の変更として表示されます RFC 8259、JSON オブジェクトは 無秩序 名前/値のペアのコレクション。 2 つのドキュメントはバイトごとに異なったもので、意味的に同一です。 JSON を行ごとに比較するツールが間違った質問に答えています。
あ JSON 差分ツール 正しいものに答えます。 両方のドキュメントをツリーに解析し、比較します。 値: このキーが追加され、そのキーが削除され、この値が X から Y に変更され、 - 週末を保存していたものが、当時ブラウザのタブに存在していた場合 - この値が変更されました タイプ。 ツールズ.dev の差分チェッカーを構築したとき、型変更検出はリストの最初の機能でした。これは、テキストの差分が構造的に表面化できず、実際のシステムを破損することが最も多い変更のクラスであるためです。
このガイドでは、構造比較の仕組み、配列順序がいつ、いつ、および #39;重要なのか、およびデバッグ ワークフロー (API 回帰、構成ドリフト、パッケージ マニフェスト監査) (JSON 差分が毎週支払われます) について説明します。
tl;dr: 2 つの JSON ドキュメントを Toolz.dev JSON ディフ チェッカー 構造比較を取得します。次のような正確なパスを使用して、追加、削除、および変更されたキーを取得します。
features.rateLimitやusers[3].emailープラス値が変化したときのフラグ付けを別途行う タイプ (3000→"3000"バグ)。 キーの順序と書式設定が誤検知を生成することはありません。 すべてがブラウザで実行され、何もアップロードされません。 それとペアリング JSON フォーマッタ 最初にドキュメントをきれいにするには、 テキスト差分ツール 行が実際に重要なコンテンツの場合。
構造的に異なる JSON とはどういう意味ですか?
構造差分は、両方の文書を実際のデータツリーに解析し、キーごとに、要素ごとに、一緒にそれらを歩きます すべてのノードで、それは尋ねます: このキーは両側に存在しますか? 値は同じタイプですか? 等しいですか? 出力 isn' t " line 14 changed" - it' s あなたのデータに関する事実のリスト:
versionから変更されました"1.4.0"にする"1.5.0"features.metrics付加価値で追加されましたtrueportタイプを数値から文字列に変更tags[2]付加価値で追加されました"monitored"
それぞれの違いは完全な JSON パスを運ぶため、深く入れ子になったドキュメントでは、どこを見ればよいかが正確にわかります。 users[12].address.postalCode スクロールは必要ない、どのユーザー、どのフィールドを表示しますか。
テキストの差分との対比は、実際のドキュメントでは最も顕著です。 取る package.json 別のnpmバージョン、バックエンドチームがシリアライザをアップグレードした後のapiレスポンス、またはフォーマッタを介して実行されるコンフィグファイルによって再生成されました。 text diff: 数百の変更行 Structural diff: 実際に起こった3 つの変更、または何もないという正直な答え - " 構造的に同一" - それ自体が価値のある危険なリファクターを生成したことを確認します ゼロ データの変更は、私がこのツールに到達した理由の半分です。
There' s 行差のための場所, 明確にするために. 散文, コード, HTML, 物理的なレイアウトは意味を運ぶものは何でも - that& #39; s テキスト差 領土。 しかし、JSON のレイアウトは仕様上意味を持ちません。そうでなければノイズが発生していると思われる比較では、目でフィルタリングする必要があります。
タイプの変更が独自のカテゴリーに値するのはなぜですか?
データの他のすべてのビューでは目に見えないため、デバッグが惨めな方法で物事を壊します。
1099 あんど "1099" ログ ファイル、端末、およびほとんどのテキスト差分で同じようにレンダリングします。引用符は午前 2 時に見逃しがちです。しかし、入力された消費者にとって、それらは異なる値です。 JavaScript' s === 比較を拒否します。 JSON スキーマを宣言する "type": "integer" 検証に失敗します。 マーシャリングを解除する Go サービス int64 エラーを返します; Javaで厳格なJacksonデシリアライザがスローします。 PHPは、ゆるい比較で寛容であることは有名ですが、厳密な型を有効にした瞬間 - 現代のすべてのLaravelコードベースはそうすべきです - "1099" お金になるのをやめ、例外になり始めます。
一番厄介な部分は どこ これらの変更は、そこから来ています。 開発者から意図的に値を編集することはほとんどありません。 シリアライザー スワップ、ORM アップグレード、データベース列が移行することから生まれます。 INT にする VARCHAR、数字を文字列化するキャッシュ レイヤー、または意味のある API ゲートウェイの「正規化」ペイロード。 誰もがそのようなことが起こったことを誰も知らないので、誰も彼らの変更ログエントリを書きません。
ということで、 JSON 差分チェッカー タイプ変更を独自のカテゴリとして報告します - ! コピー可能なレポートでは、通常の値の変化とは異なります - 古いタイプと新しいタイプが綴られています。 when you' と言う要約を見つめています 0 added, 0 removed, 0 changed, 1 type changed、1 つの道を読む前に、どんなバグを探しているのかを正確に知っています。
2 つの json ファイルをツールと比較するにはどうすればよいですか?
ステップ 1: 両方のドキュメントを貼り付ける
オリジナル (または既知の) JSON は左側のパネルに移動し、右側の JSON を更新 (または疑わしい) します。 規則は出力の読み込みにのみ重要です。「追加」は、右側に存在するが左側ではなく、「削除」が逆であることを意味します。 作業環境と壊れた環境を比較している場合は、左側に作業をすると、「何が変わったか」という差分が表示されます。
そこ' S は、値の変更、追加、型の変更、配列の成長など、すべての差分タイプを実行する小さなサービス構成を両方のパネルに入力するサンプル読み込みボタンです。これは、出力の読み取り方法を学習する最速の方法です。
ステップ 2: 配列の順序が重要かどうかを判断する
これは、検討する必要がある 1 つのオプションであり、正しい答えは、配列によって異なります。 平均ー以下で詳しく説明します。 default is order-sensitive, which matches the JSON specification. tick "配列 order" を無視する 配列が意味的にセットされている場合。
ステップ 3: 比較する
いずれかのドキュメントは、何かが比較される前に検証されます。 どちらかの側に構文エラーがある場合 - 末尾のカンマ、一重引用符、引用符で囲まれていないキー、通常の容疑者 - parser' s の正確なメッセージ、そして、決定的に、 どの辺 それはから来ました。 サイレント エラーも、半解析されたゴミも比較できません。 JSON が有効かどうかわからない場合は、 JSON フォーマッタ まず、1 つのステップで検証してきれいに印刷します。
ステップ 4: 概要を読み、次に表を読みます
概要行には、カテゴリごとにカウントが表示されます - 追加、削除、変更、タイプ変更 - 必要なものはすべてこれだけです。 " 47 追加、0 削除、0 変更" API バージョンのバンプ後に、新しいフィールドのみを意味します: 安全です。 "0 追加、3 削除"消費者が依存する可能性のあるフィールドを意味します。安全ではありません。以下の表は、パス、古い値、新しい値を使用してすべての違いをリストしており、長い値で読みやすくするために切り捨てられています。
ステップ 5: レポートをコピーする
[レポートのコピー] ボタンは、プレーン テキストの要約を生成します。 + / - / ~ / ! マーカーとフルパス - プルリクエストコメント、Slack インシデントスレッド、またはチケットに直接貼り付けるように設計されています。 "ここと#39;ステージングとプロダクション構成の間で何が変わったのか、"ワンクリックでレシートを押します。
配列の順序を無視するのはいつですか?
JSON配列は仕様 - により順序付けされます [1, 2] あんど [2, 1] は異なるドキュメントであり、デフォルトの比較ではそれが考慮されます。 ただし、仕様では意図ではなくコンテナーが記述されており、実際には配列は 2 つの異なる方法で使用されます。
配列としての配列、位置が意味するところ: 順番に実行するミドルウェアチェーン、移行リスト、ソートされたリーダーボード、ページ付けされた結果 これらの並べ替えは実際の変更です - 実行されるミドルウェアスタック auth のあと handle は別の (そしておそらく壊れた) アプリケーションです。 秩序感に敏感な状態を保ちます。
配列をセットとして位置が偶然の場合: タグリスト、ロールの割り当て、機能フラグ、データベースクエリによって返される ID はありません ORDER BY。 Postgres は、異なる実行で同じ行を異なる順序で返すという完全に権利の範囲内にあり、そのために差分が点灯した場合は、that' s ノイズ。 "Ignore array order" オプションは、 - 位置に関係なく要素が一致するためです ["admin", "editor"] 等しい ["editor", "admin"]。
私の経験則 API ペイロードの比較: バックエンドが明示的な並べ替えを適用する場合、配列をシーケンスとして扱い、そうでない場合は、作成者が認識したかどうかに関係なく、データに関する真実を説明します。
構造の差分とテキストの差分と手動検査
| 構造 JSON の差分 | テキスト/行の差 | それを目撃して | |
|---|---|---|---|
| 再注文されたキー | 違いは報告されていません | 移動するすべての行にフラグが立てられています | 変更を見逃しやすい |
| 再フォーマットされた空白 | 違いは報告されていません | すべてがフラグされています | ふふふ |
タイプの変更 (1 → "1") |
タイプ変更としてフラグが立てられています | 線の海に浮かぶ 2 つの文字 | ほとんど見えない |
| ネストされた変更場所 | 正確なパス: a.b[2].c |
行番号 フォーマットされた テキスト | 手動トラバーサル |
| 配列の再配列 (意図的) | フラグが立てられている (または無視されている場合は、あなたの選択) | フラグ付き | 配列のサイズによって異なります |
| に最適 | JSON、API ペイロード、構成 | コード、散文、マークアップ | 2 行のドキュメント |
| 障害モード | 有効な JSON には何もありません | 誤検知は本当の変化を埋める | 人間の疲労 |
正直な要約: テキスト差分 aren't wrong, they're answering a differ question - "did the bytes change?" JSON の場合、ほとんどの場合 "did the でー 変更?」、これらの質問には驚くほど頻繁に異なる答えがあります。
JSON 差分の実際のワークフローは何ですか?
API 回帰のデバッグ
私のWebhookストーリーからのワークフロー、今体系化: 変更前からのペイロード (ログ、記録されたフィクスチャ、あなたのテストスイート& #39; sスナップショット) と、その後からの1 つをキャプチャします 左パネル、右パネル、比較. diffは、プロバイダ& #39; s変更ログが行った& #39; t - どのフィールドが移動し、どのタイプが変更され、静かに消えたかを秒単位で伝えます サードパーティのAPIがバージョンバンプを発表するたびに、これを行います 前に 古いバージョンの Sunset が発生し、レポートをアップグレード チケットに提出します。
構成ドリフトをキャッチ
ステージング作品、プロダクションdoes& #39; t、そして両方とも " 同じconfig." からデプロイされました 彼らは? 両方をエクスポート - 環境JSON、a docker inspect 出力、Kubernetes ConfigMap でダンプされます -o jsonー そしてそれらを差分します Configのドリフトは ほぼ常に1 つか2 つのキーで パス列はそこにまっすぐ進みます これは拍です diff <(jq -S . a.json) <(jq -S . b.json) 端末で、型の変更もキャッチするため、 jq-正規化されたテキストの差分は、ほとんど目に見えないように表示されます。
ロックファイルとマニフェストの変更の確認
あ package.json や composer.json それは競合するマージ、またはフレームワークアップグレード後に生成されたopenapi仕様によってめちゃくちゃになった: structural diffは、再生成されたフォーマットのノイズなしで依存関係の変更を示します。 WordPressプラグインの作業の場合 - WP AdminifyはJSONとして設定を出荷します - 私はリファクタdid& #39; tが依存するキーをドロップすることを確認するために、リリース間でエクスポートされた設定スキーマを誤って削除すると、aとして表示されます - 行; 4,000 行の設定のテキストの差分では、何も何も表示されません。
データ移行の確認
前: 代表レコードを JSON としてエクスポートします。 移行後: 再度エクスポートします。 差分には、移行が意図した変更と正確な変更が表示されます。 それ以外は。 「構造的に同一」という記録にある、これまでに実行した最も安価な回帰テストは、触れられてはならない。 これは、表形式のエクスポートを変換するのとよく合います。 CSVからJSONへ データが CSV としてデータベースから出てきたとき。
環境応答の比較
2 つの環境で同じエンドポイントをヒットすると、応答が異なります。 フィールドに存在するが、実稼働に欠けているフィールドは、通常、機能フラグ、古い展開、または設定されなかった環境変数を意味します。 要約だけでも、それを診断することがよくあります。
クライアント側の処理がこのツールの場合、ほとんどの場合よりも重要なのはなぜですか?
JSON の差分に何を貼り付けるかを考えてみましょう。顧客の電子メールを含む API 応答、内部ホスト名を含む構成ファイル、支払いメタデータを含む Webhook ペイロード、データベースのエクスポート。これはまさに漏れてはいけないデータであり、どのオンライン ツールが受信したかを誰も監査していないまさにその瞬間、つまり事件の途中で貼り付けられました。
ザ・ Toolz.dev 差分チェッカー ブラウザで完全に解析して比較します。リクエストはドキュメントをどこにでも持ちません。ページが読み込まれるとツールはオフラインで動作します。ネットワークを切断して再度比較することで検証できます。これは、アーキテクチャを変更する可能性のあるプレミアム機能またはポリシーの約束です。it's。比較ロジックは、メモリ内の解析された 2 つのツリーで動作する純粋な JavaScript です。データを送信するサーバー コンポーネントはありません。
同じプライバシーの議論がツールボックス全体に当てはまります - it'その理由は次のとおりです Toolz.dev の開発者ツールキット ブラウザ優先で構築されていますが、異なるツールがその場所にあります '比較するため、最も深刻です 2つ プロダクション ドキュメントは、貼り付けの露出を 2 倍にします。
どのくらいの大きさのドキュメントを比較できますか?
比較は、両方のツリーのすべてのノードを 1 回訪問するため、作業はドキュメント サイズに比例してスケーリングされます。 実際には、数百キロバイトのドキュメントは、即座に比較されます。最新のラップトップに似たものでは、1 秒未満で 1 桁の低低を実現します。数十メガバイトは機能しますが、ブラウザーは両方のドキュメントを解析し、両方のツリーを同時にメモリーに保持する必要があるため、機能します。
非常に大きなペイロードのための2 つの実用的なヒント まず、文書の一部だけを気にしている場合は、そのサブツリー - ペーストだけを比較してください response.data.items 封筒全体ではなく、両側から。 第二に、diff が何千ものエントリを生成する場合、通常は片側が異なる符号です 形 (オブジェクトに包まれた配列、追加のネスト レベル) - スクロールする前に最初のいくつかのパスを確認します。それらと #39;あなたと #39; が 1 つの構造変化をカスケード的に調べているのか、それとも何千もの本物の構造変化を調べているのかを教えてくれます。
フェイク
2 つの JSON ファイルをオンラインで比較するにはどうすればよいですか?
を開きます JSON 差分チェッカー、左側のパネルに1 つのドキュメントを貼り付け、右側にもう1 つのドキュメントを貼り付け 、 「比較」をクリックします。 「追加、削除、変更、型変更したすべての値の分類されたリストを、正確なJSONパスで取得します。両方のドキュメントは完全にブラウザで処理されます - どのサーバーにも何もアップロードされません。」
JSON データが同じであるのに、なぜテキストの差分が多くの変更を表示するのですか?
テキスト差分は線を比較し、JSON では同じデータをさまざまな方法で書き込むことができるためです。 並べ替えられたキー、異なるインデント、および空白はすべて、データを変更せずにテキストを変更します。 構造的な差分は、両方のドキュメントを最初に解析し、実際の値を比較するため、書式の違いは、報告された変更をゼロにします。
JSON オブジェクトのキーの順序は重要ですか?
いやー RFC 8259 は、JSON オブジェクトを、名前/値のペアの順序付けられていないコレクションとして定義しているので、 {"a":1,"b":2} あんど {"b":2,"a":1} は同じオブジェクトです。 diff チェッカーはキー名でオブジェクトを比較し、変更として並べ替えを報告することはありません。対照的に、配列要素の順序はデフォルトで重要です。配列は仕様で順序付けされます。
「配列の順序を無視」オプションはいつ使用すればよいですか?
配列がシーケンスではなく意味的にセットされているときに使用します - タグリスト、ロールコレクション、ソートされていないデータベースクエリからのID オプションをオンにすると、 [1,2,3] あんど [3,1,2] 等しく比較してください。 順序付けされたミドルウェア チェーン、ランク付けされた結果、ページ リストなど、ポジションが意味を持っている場合は、それをオフのままにします。
タイプチェンジとは何ですか?また、なぜ別にフラグが立てられるのですか?
型変更とは、値が & #39; s JSON 型が、たとえ似ていてもドキュメント間で異なる場合、つまり数値です 3000 文字列になる "3000" は、クラシックなケースです。 厳密な型のコンシューマー、スキーマの検証、および厳密な等しいチェックを壊して、テキストの差分とログではほとんど見えないため、別々にフラグが立てられます。 これは、API 統合回帰の最も一般的な原因の 1 つです。
比較結果をチームと共有できますか?
はい。 [レポートのコピー] ボタンは、プレーンテキストの差分レポートを生成します。 + (追加)、 - (削除) ~ (変更)、および ! (変更と入力) マーカーとすべての違いに対する完全な JSON パス。 プル リクエスト コメント、スラック スレッド、および発行トラッカーにきれいに貼り付けられるようにフォーマットされています。
本番 API のレスポンスをツールに貼り付けても安全ですか?
はい。 解析と比較は、ブラウザのJavaScriptで完全に実行されます - データを使用してネットワークリクエストが行われず、何もログに記録または保存されず、ツールはオフラインで動作し続けます。これにより、顧客データ、内部ホスト名、または資格情報を含むペイロードに対して安全になりますが、秘密を共有する前に編集します 報告 まだあなたにあります。
ドキュメントの 1 つが有効でない場合はどうなりますか?
ツールは比較する前に両側を検証し、parser' s の正確なエラーメッセージを、それがどちらから来たのか - 左か右かとともに報告します 一般的な犯人は、コンマの末尾、二重ではなく一重引用符、引用符で囲まれていないキーで報告される問題を修正するか、またはドキュメントを貫通して実行します JSON フォーマッタ 問題を見つけて、もう一度比較してください。
構造比較は、どのバグを変更するかを変更するツールの 1 つです。 みるの. Text diffs answer "did the bytes change?"; JSONの場合、重要な質問は "did the data change?" - そして、システムを実行するAPIペイロード、コンフィグ、マニフェストの場合、 JSON 差分チェッカー データがマシンから離れることがない状態で、ブラウザで数秒で応答します。書式設定、検証、変換などの JSON ワークフローがさらに多く存在します コーディング ツール ガイド。



