はじめに
何がやりたかったか
- jsonを返却してくれるAPIがあって、その改修をしたい
- 共通のUtilクラス変更したり、ライブラリの更新したりする
→ 1つのAPI改修に対して影響範囲が広くなりそう - テスト書きづらいつくりしてる
じゃあ返却されるjsonの差分とってまず動作担保しよう!
要件
- java(Kotlinも可) でやる
- 対象のAPIがjavaで実装されているので、同じ言語・フレームワークで比較できるようにしておく。後々の運用時学習コストを下げるため。
- 差分の場所、内容がわかる。
- 差分ありますよ!じゃなくて、どこで差分が出てるかがわかる
- 文字列差分じゃなくてちゃんとオブジェクト差分
- さくっとやりたいので使えるライブラリあるならそれを使う
結論
経緯とかいろいろ書くより、何やったか(使ったか)を書いておきます。
これ見て満足した人はこのページそっと閉じて実装しに行ってください(バイバイ)
zjsonpatch を使いました。
差分チェック
// {"a": 0,"b": [1,2]}
JsonNode jsonA = jacksonObjectMapper.readTree(jsonAString);
// {"b": [1,2,0]}
JsonNode jsonB = jacksonObjectMapper.readTree(jsonBString);
JsonNode patch = JsonDiff.asJson(jsonA, jsonB)
patch.toString() // [{"op":"move","from":"/a","path":"/b/2"}]
op
の部分に種別が入ります。
削除で remove
, 追加で add
とか。
path
には対応するjsonのパスが入ります。
あとは種別に応じて、例の from
みたいにオブジェクト生成されます。
調べたこととか
json-patch も同じことができる模様。
ただ、[stackoverflow] (https://stackoverflow.com/questions/6526911/best-way-to-compare-2-json-files-in-java) の回答者が以下のように書いてくれてます。
This library is better than fge-json-patch (which was mentioned in another answer) because it can detect items being inserted/removed from arrays.
Fge-json-patch cannot handle that (if an item is inserted into the middle of an array, it will think that item and every item after that was changed since they are all shifted over by one).
【訳(ありがとうGoogle翻訳)】
このライブラリは、fge-json-patch(別の回答で言及されています)よりも優れています。
アレイから挿入/削除されるアイテムを検出できるためです。
Fge-json-patchはそれを処理できません(アイテムが配列の中央に挿入されると、すべてのアイテムが1つずつシフトされるため、アイテムとその後のすべてのアイテムが変更されたと見なされます)。
配列の差分比較がちゃんとできないっぽい。
ライブラリの更新日を見ても今回紹介したものの方がよさそうなのでこちらを採用しました!
おわりに
jsonの比較したいと思って調べても英語記事とか独自実装とか多めで、さくっと見つけられる情報あるといいなと思って書いてみました。
この記事見つけてくれた方のお役に立てば幸いです。