RustのGraphQLサーバライブラリJuniperを試す
こんにちは、ナカエです。
GraphQL
GraphQLの名前を見る機会が増えてきました。つい先日もGitHubのAPIが話題になったりしていましたね。
GraphQLもまた、RESTを完全に置き換える銀の弾丸ではないことは明らかですが、複数のマイクロサービスやAPIを集約するBFFの文脈での活用事例は面白そうです。個人的にはサーバ側の実装コスト・セキュリティ・パフォーマンスなどのハードルが、今後どの程度下がるだろうかと思って眺めています。
GraphQLサーバを試すハードルは今でもそう高くありません。GitHubで検索してみると、node.jsを始めとする言語で書かれたGraphQLサーバのライブラリが見つかります。
https://github.com/search?p=1&q=graphql&type=Repositories
Juniper
今回はRust製のJuniperを利用して、GraphQLサーバを立てました。
Juniperには、RustのWebフレームワークRocketやIronと合わせて利用するためのサンプルコードが含まれています。RocketのファンなのでRocketで試してみることにしました。
テスト用のプロジェクトを作る
RustのツールチェインrustupでRustのnightlyをセットアップしておきます。今回利用したバージョンは1.20.0-ngihtlyです。
$ rustup show
(略)
active toolchain
----------------
nightly-x86_64-apple-darwin (default)
rustc 1.20.0-nightly (2fbba5bdb 2017-07-04)
プロジェクトの初期化
$ mkdir graphql_test
$ cd graphql_test
$ cargo init --bin
Cargo.tomlの設定
juniperのfeaturesはRocketとの統合のためにrocket-handlers, サンプルのGraphQLスキーマを借りるために、expose-test-schemaの2つを指定します。
[package]
name = "graphql_test"
version = "0.1.0"
[dependencies]
juniper = { version = "0.8.1", features = ["rocket-handlers", "expose-test-schema"] }
rocket = { version = "^0.2.8" }
rocket_codegen = { version = "^0.2.8" }
src/main.rs
Rocket用のサンプルコードをそのままmain.rsとして使います。
実行
cargo runを実行するとコンパイル後にRocketのサーバが立ち上がります。
クエリを投げる
クエリ用のエンドポイントは http://localhost:8000/graphql となっています。
Juniper付属のテスト用スキーマは、例によってスターウォーズの登場キャラクターです。
http://localhost:8000/graphql?query={hero(episode:JEDI){id%20name%20friends%20{name}}} のようにクエリを投げると下記のようなレスポンスが返ってきます。
{
"data": {
"hero": {
"id": "2001",
"name": "R2-D2",
"friends": [
{
"name": "Luke Skywalker"
},
{
"name": "Han Solo"
},
{
"name": "Leia Organa"
}
]
}
}
}
スキーマ定義のコードを眺める
スキーマはsrc/tests/schema.rsで、実際の値はsrc/tests/model.rsに記述されています。
まとめ
サンプルコードを動かしただけですが、GraphQLサーバに対するクエリにレスポンスが返ってくるのを確認できました。
実用のためには、テスト用にHashMapで実装されていた部分を外部API・マイクロサービスやデータベースへの問い合わせに入れ替え、認可とアクセス制御を追加することになるでしょう。実用の予定はまだありませんが、GraphQLサーバ入門のハードルは先人たちのライブラリによって思った以上に低くなっていると感じました。