odiak's blog

JSON の構造をチェックするツールを作った

API のテストをするときなどに、レスポンスの形式が正しいかどうかを確認したいときがある。

しかし、レスポンスの中身をいちいち assersion するのはだるい。 返ってくるであろう結果を配列やハッシュで書いておいてそれと比較するという手もあるが、それは少し窮屈だし、あらかじめ分からないデータもある。

そこで、 JSON の構造を Ruby の DSL で書いておいて、返ってきたデータと比較できる、 json_structure というツールを作った。

https://github.com/odiak/json_structure

使い方はこんな感じ。

structure = JsonStructure.build do
  object(
    username: string(min_length: 1),
    phone_number: string(format: /\A(?:\d+-)*\d+\z/),
    height: number(min: 0),
    role: value('admin') | null,
    favorites: array(string),
  )
end

structure === {
  username: 'foo',
  phone_number: '090-0000-0000',
  height: 169.3,
  role: 'admin',
  favorites: ['banana', 'apple'],
}
# => true

structure === {
  username: '',
  phone_number: '+8190-0000-0000',
  height: -150,
  role: 'superman',
}
# => false

DSL を使わずに書くと、こんな感じ。

JS = JsonStructure

structure = JS::Object_.new(
  username: JS::String.new(min_length: 1),
  phone_number: JS::String.new(pattern: /.../),
  height: JS::Number.new(min: 0),
  role: JS::Value.new('admin') | JS::Null.new,
  favorites: JS::Array.new(JS::String.new),
)

JS::Object_, JS::Array, JS::Number などのクラスは === メソッドでデータの構造が正しいかどうかをチェックできるようになっているので、それらを組み合わせることでいろいろな構造を定義することができる。

ついでなので、rugygems にも公開してみた。 bundle gem でテンプレートを生成してくれるのでかなり楽だった。

https://rubygems.org/gems/json_structure


P.S.

Object という名前のクラスは作れないと勘違いして Object_ にしていたけど、もう一度確認したら普通にできた。後で書き直そうっと。