Revisitng GraphQL

GitHub が GraphQL をサポートしたというニュースに驚き、久しぶりに資料を眺めている。

以前みた時は、クライアント側は嬉しいけれどサーバ側を書くのが大変そうな印象だった。GraphQL サーバのフレームワークたちは、フレームワーク側がクエリを型単位のリクエストに分解する。フレームワークを使う側はデータを取得する "resolver" 一式を個々の型に実装する。

バックエンドが microservices や nosql になってしまっている大規模サービスなら悪くないデザインだけど、RDB から一撃で色々ひっこぬきたい人たちには嬉しくなさそうに見える。実質上 ORM の one-to-many association で lazy evaluation をするみたいになってしまい、性能上の問題もありそうだし。(なおこの問題を N+1 problem と呼ぶことを今更知った。) API endpoints をトラバースする手間がクライアントサイドからフロントエンドのサーバに移るだけだと、仕組みの大袈裟さに対する有り難みが小さく感じる。GraphQL の issue にもその申し立てがある

調べてみると, GraphQL ライブラリのいくつかは N+1 problem への処方箋を持っていた。具体的には "N 回のリクエスト" を "N 個のオブジェクトを取り出す 1 回のリクエスト" にまとめようとする。なので N+1 が 1+1 になる。1 ではないけれど N+1 よりはだいぶいい。ただネストが深くなるとどこかで N が顔を出しそうではある。

Scala の GraphQL 実装である Sangria はバッチ化したいオブジェクトを Deferred という generic type で表す。するとフレームワーク側が同じ型の deferreds をまとめ、一撃で取得するリクエストを投げ、その結果をまとめて返してくれる。らしい

Facebook が公開している DataLoader という JS のライブラリも似た感じ。データをすべて Promise でラップし、Promise の解決をバッチ化する。フレームワークにくっついておらずAPI が素直、コードも小さい。これを書いた人は Promise わかってんなというかんじがして良い。README には graphql-js と組み合わせてつかう例が載っている。関係ないけどその README 冒頭でちらっと書いてある background story がよい。その Ent っていうフレームワーク、むかしなんかの techtalk で聞いたよ! などと FB tech watcher としてにわかに盛り上がる。

Ruby では graphql-batch を使うと Github のブログに書いてある。読んでないけど似たようなもんなのでしょう。Intuit も使っているというから来年の確定申告がちょっとだけ楽しみになった...とおもったら TurboTax じゃなくて QuickBook か。残念...どうでもいいですが...

という具合に当初の印象に反しサーバ側もじりじり使いやすくなりつつあるかんじなのだろうか。

クライアント側。JS ならさておき Android はどうなのかなあ。graphql-java というのをつかうっぽいけれど、データを Java のオブジェクトにマップしてくれないとつらい。Java のクラスで GraphQL の型を表現する graphql-java-annotations なんてのがあるからあと一歩。Facebook がどうしているのか知りたい。ほんとに Android 向けで GraphQL 使ってるんだろうか。まあビルドシステムとべったりくっついててオープンソースに切り離せないとかなんだろうね。

現状だとまだ React スタックな人向けのフレームワークだなという印象。React-Redux-Relay-GraphQL のなにかをつくるのは楽しそうではある。AWS Lambda の API gateway みたいなレイヤが GraphQL を解釈して背後の lambda に dispatch してくれるなどの支援がすすみ、趣味プログラマからも手が届くテクノロジになってほしいもんです。