まっしろけっけ

めもてきなやーつ

GraphQL の spec に関してアレコレ考えている

はじめに

最近 GraphQL を本格的に使い始めるぞいとなってんですよ。
経緯は下記参照

それでいくつか filed とか定義してデータ取れるようにしつつ rspec で test 書いててう〜むとなったので自分の考えをまとめて世の知見を知りたいとなったという経緯

前提

環境はこんな感じ

  • Rails なアプリケーション
  • graphql-ruby
  • graphql-batch
  • graphql-guard

その1 request spec は書く必要ないのでは?

実際に呼ばれるのは HogeSchema.execute なので request spec では GraphQL API に対して execute に渡される引数周りのチェックをすれば良いと考えた。
expect(HogeSchema).to receive(:execute).with(hoge, hoge, hoge) くらいを引数のパターン分あると良さそう。

何故ならば実際のクエリ書いてテストしていくとネストの深い巨大なクエリが出来上がって、
そのクエリの検証も辛いしレスポンスの json の検証もネストが深くなり辛いということになると考えたから。

実際に 4 種類ほどのデータ取れるようにしただけで辛いなって気持ちになったのでこの考えに至った。
ではどういうことをテストすれば安心を得られるだろうか?と考えた結果がその 2,3 になる

その2 GraphQL::ObjectType 毎に spec を書いていく

GraphQL で大事なのはそれぞれの GraphQL::ObjectType で定義された各スキーマ要素をチェックしていくと良さそう

どんな field が定義されているか?をチェックする。
PostType = GraphQL::ObjectType.define do
  name "Post"
  description "A blog post"
  field :id, !types.ID
  field :title, !types.String
  field :body, !types.String do
    guard ->(obj, args, ctx) { ... }
    resolve ->(obj, args, ctx) { ... }
  end
end

上記のような PostType があった場合は下記のようにチェックする。

describe PostType do
  subject { described_class.fields.keys }
  it { is_expected.to eq(["id", "title", "body"])
end

この他にも field 毎の型定義も想定した通りになっているかチェックしておきたい。
Ruby とかやってると型とかそんなに気にしないかもしれないけれど静的型付け言語がこの API を使うとなった場合はいい加減な型定義は出来ないのでちゃんとしておきたいという気持ち。

しかし一個一個書いていくのもダルいなと感じ他ので db のカラムのデータ型がそのまま field になっている場合が多いと考えるとある程度自動でチェックする仕組みは用意できそうなのでは?と考えたのでちょっとゴニョゴニョしようかなと考えている
db 以外の field はちゃんと個別チェックする。

graphql-guard の設定が正しいかをチェックする

これは README に書いてあるのだけれど下記のように呼び出せるので返り値を適切にチェックすると良さそう。

describe PostType do
  it do
    body = PostType.field_with_guard('body')
    expect(body.guard(obj, args, ctx)).to be_truthy
  end
resolve もチェックする

これも上記と同じようにチェックできる

describe PostType do
  it do
    expect(PostType.fields["body_url"].resolve(obj, args, ctx)).to eq("...")
  end

しかしこの方法だと resolve 内で graphql-batch の loader を使ってる場合にエラーが出るんでどうしたら...というのが悩み

その3 実際のクエリ書いてチェックする必要ってある?

その1 とも被る内容なのですが、その2 の spec をしっかり書いていれば schema の定義はしっかりと出来ているわけでその状態でデータ上手く取れない〜となった場合はクエリが悪いのだろうということになると考えられるからです。

それでも心配なら全スキーマを取ってくるクエリ書いてエラーでないねっていう程度はいいかもしれん(けど、factory bot でデータを用意するのすらだるい)

でも個別(field 毎)のエラーのチェックはクエリ投げないとダメなんかな〜という感じだが現状エラーが出るようなパターンを書いてないのでなんとも言えない

最後に

まだ本格的に使い始めて3,4日程度なのと通常の query のみで mutation に関しては全くという感じなので上に書いた考えは変わってくるかもしれない。

ペパボ社内で他に GraphQL を使っているサービスがあったので、どういう方針なんって聞きにいくついでに今の考えまとめようと思って雑に gist 書き出したらこういう考えに至った。
でそれを共有したらこんなこと考えてたんですよ〜とやまちゃんがナイスなブログを書いてくれて優秀な若者便利!!1となった

blog.kymmt.com