GraphQL サーバー on Kotlin ことはじめ (DroidKaigi 2019 に参加して GraphQL について学んだ)
DroidKaigi 2019 にスポンサー枠で参加しました。 弊社では Android アプリエンジニアをはじめとして各分野のソフトウェアエンジニアを募集しております。 人生を豊かにするプロダクトの開発や、大きな企業でのソフトウェア開発をいかに改善していくかといったところに興味がある方はぜひお声がけください! いっしょにやっていきましょう!
それはともかく DroidKaigi、様々なセッションがあって素晴らしかったですね。 運営、スピーカー、スポンサー、そして参加者の皆様、ありがとうございました。
私個人としては、GraphQL についての知見を得られたのが大きな収穫でした。
本記事について
本記事は、GraphQL サーバーを Kotlin で立てるにあたって、仕組みを学んだ軌跡を残すものです。 GraphQL 自体の初心者が、Kotlin で GraphQL サーバーを実装する際には参考になると思います。 本番環境で使える技術とかを紹介しているわけではないのでご注意ください。
DroidKaigi 2019 と GraphQL と私
GraphQL についてはこれまでも雰囲気では知っていたのですが、はてなの id:takuji31 さんと id:funnelbit さんの発表で改めて GraphQL の良さを感じました。
ところで、上記の発表では主にクライアントサイド視点での GraphQL の話が主で、サーバーサイドの実装がどうなるのかが非常に気になるところです。 クエリのパースから実際のデータの取得処理まで、素朴に実装しようとすると難しそうに感じます。 懇親会のときに id:takuji31 さんと id:funnelbit さんに聞いてみたところ、「サーバーサイドの実装者ではないのでそこまで詳しくはないが、言語ごとにいい感じのライブラリがあるから、割と何とかなるっぽい」 とのことでした。
ということで GraphQL の Kotlin サーバーに詳しい人に教えを請いたい〜、と思っていたら shiraji さんが導いてくれて gfx さんや taka さんたちから知見を吸わせてもらえました。 神か! (ありがとうございました。)
知見
- GraphQL をするならまずは gfx さんのこの記事を見ろ! : 「GraphQL」徹底入門 ─ RESTとの比較、API・フロント双方の実装から学ぶ - エンジニアHub|若手Webエンジニアのキャリアを考える!
- GraphiQL というブラウザ上で動く GraphQL IDE が存在する : graphiql - npm
- JVM 系言語における GraphQL の実装は graphql-java が一番良さそう。
- Spring Boot で graphql-java を使った実装のサンプルは Ubie 社 (shiraji さん) が公開しているぞ! : GitHub - ubie-inc/kotlin-graphql-sample: Sample implementation of Kotlin+Spring+GraphQL
- graphql-java を Spring Boot で使うときの便利ライブラリの依存関係は taka さんがまとめてくれている : コードで見る graphql-java 関連ライブラリの関係性 - Qiita
自分で動かして試してみる
上記のようなページを見ることでなんとなく Kotlin での GraphQL サーバーサイド実装をどうすれば良いのかが見えてきましたが、Spring Boot を使った上記の例では便利ライブラリが詳細を隠ぺいしてくれているので細かな理解ができませんでした。 というわけで自分でも手を動かして試してみます。
graphql-java を試す
graphql-java は GraphQL のスキーマやクエリのパース、バリデーション、実行といった機能を提供するものです。 HTTP のインターフェイスは提供しません。 Kotlin で GraphQL の挙動を試したい場合は、まずは graphql-java を生で触るのが良いでしょう。 下記のドキュメントを見ながら進めると良いと思います。
外部 IO 無しで簡単に試せるので、最初のとっかかりとしては非常にやりやすいと思います。 私は下記のようなコードを書いて試していました。
- Hello world 的なやつ : https://github.com/nobuoka/kotlin-graphql-playground/blob/10d3f14c13b9d0e6d95fbbe82d1df85314227ba6/playground/src/main/kotlin/1-HelloWorld.kt
- 条件を指定してデータをフェッチするやつ : kotlin-graphql-playground/2-Schema.kt at 10d3f14c13b9d0e6d95fbbe82d1df85314227ba6 · nobuoka/kotlin-graphql-playground · GitHub
まだリソース間に関連がある場合などは試せていません。
HTTP インターフェイスとつなぎこむ
GraphQL のサーバー・クライアント間の通信プロトコルについては、(おそらく) 仕様上は何も定められていなさそうです。 公式サイトに、HTTP での通信についてベストプラクティスとして書かれています。
これに従ってサーバーサイドの HTTP のエンドポイントを実装し、graphql-java とつなぎこむ、という感じにすれば良さそうです。 もともとの GraphQL のクライアント・サーバー間のやり取りがシンプルなので、HTTP のエンドポイントとしての実装もシンプルになります。
細かなエラーハンドリングなどはできていませんが、Ktor で実装すると以下のような感じになりました。
GraphiQL を使ってみる
ここまでくると自分のサーバーで GraphiQL も提供したいですよね?
GraphiQL の JS ライブラリは、npm パッケージとして配信されています。
自分で HTML ファイルや CSS ファイル、JS ファイルをビルドすることもできますが、既にビルドされている JS ファイルを使って簡単に GraphiQL のエンドポイントを生成することもできます。 使い方の例は GraphiQL のリポジトリに含まれています。
上記 HTML ファイルを自分のサーバーから配信すれば、GraphiQL が提供されます。 ただし、依存するリソースである graphiql.css と graphiql.js をどうにかする必要があります。 (上記の HTML そのままの場合は、これらのファイルも同じサーバーから配信する必要があります。)
今回は手軽に試したかったので CDN で配信されているものを使うようにしました。 下記 CDN で graphiql.css と graphiql.js が配信されています。
これを使うように書き換えた HTML をサーバーから配信すると、GraphiQL を使えるようになります。
Ktor で GraphiQL を表示させてみるところまでできた。 GraphiQL すごい♡ pic.twitter.com/jjV3Hb8ZYk
— Nobuoka Yu (@nobuoka) 2019年2月10日
おわり
というわけで初心者が GraphQL を学んでいる軌跡でした。 ここに書かれていない知見等ありましたら是非教えてくださいませ〜〜。