GraphQLが発表されて3年、日本語の紹介記事が出回りはじめてから約1年ほど経過しました。プロダクション採用例もカンファレンスやブログでちょこちょこ見かけます。

私たちSOELU開発チームもGraphQLをサービス開発に採用し、使い勝手などを探ってきました。このエントリーでは、採用してみた所感をまとめます。

本題に入る前に、先日GraphQLの入門勉強会を行いました。そのときの資料と、GraphQLを使った簡単なアプリケーション実装例を公開します。GraphQLをまだキャッチアップできていない人はまずこの資料に目を通していただくと理解が深まるかと思います。

資料

サンプル実装

GraphQLサーバの実装について

GraphQLを採用するとき、『APIサーバの実装が難しくなるのではないか』という懸念を持っていましたが、これは完全に杞憂でした。GraphQLサーバがやることは、求められたフィールドに応じてレスポンスを組み立てる関数を順次叩いていくだけです。サーバの実装コストは従来のAPI開発と変わりません。詳しくは次の章で述べますが、エンドポイントの設計に悩まなくて済む点はRESTful APIより実装負荷が低いと言えるかもしれません。

GraphQLのクエリ仕様について

GraphQLのクエリはかなり実用性を考えて設計されていると感じました。

RESTful APIでは、リソースを中心に据えてCRUD操作をHTTPメソッドと紐付けます。実際にアプリケーションを書きはじめると、取得はリソースを中心に設計しやすいですが、それ以外の操作は必ずしもリソースを中心にしていなかったり、「作成・更新・削除」の枠組みでは表現しづらいこともあります。その度に「エンドポイントは動詞じゃなくて名詞(リソース)で表現したいけど、うまく表現できない」とか「/searchくらいなら動詞でもいいか」などAPI設計の舵取りに悩むことになります。

私たちはRailsを使ってアプリケーションを開発していますが、特定のリソースに紐付かないユースケースを表現しなければいけないとき、無理やり処理を名詞に押し込んだりDHH流のControllerの書き方を試してみたり、工夫によってRESTでも表現できないことはないですが骨が折れます。

フレームワークや原則に則るならそれを守るのが鉄則ですが、CRUDに無理やり当てはめる努力が生産的なものだとはどうしても思えないでいました。

その点、GraphQLはリソースの取得についてはグラフ構造で表現するという強めの思想・原則を打ち出す一方、それ以外の操作(mutation)に関しては何の制約も設けていません。mutationは単なるRPCです。これはRESTと比べてHTTPの仕組みに則ったものでもシンプルな原則を提供してくれるものでもありませんが、非常に実用性のバランスが取れた仕様だと思います。

GraphQLのツールチェーンについて

GraphQLの実用性は先ほど述べた通りですが、開発してみて感じたメリットはむしろツールチェーンのほうにありました。

GraphQLには、問い合わせのクエリと対になる、スキーマを記述するための独自の記法があります。詳しくはこちらの記事が参考になります。

GraphQLのツールチェーンは、このスキーマを中心に作られています。例えばドキュメントを自動生成したり、GraphiQLというサジェスト付きのクエリエディタが使えたり、モックサーバを自動生成したりすることができます。

RESTful APIにもスキーマを定義する仕組みがあり、デファクトスタンダードになっているのはSwaggerです。SwaggerはXMLでAPI定義を表現します。SwaggerとGraphQLのスキーマでできることはさほど変わりませんが、個人的にはXMLよりGraphQLのスキーマのほうが可読性が高いところを気に入っています。

Appolo Clientについて

GraphQLを取り巻くツールの中でも、特に感動的だったのはAppolo Clientです。GraphQLをポジティブに捉えている理由の半分以上がApollo Clientの存在です。私はReact/Reduxの組み合わせでいくつかアプリケーションを開発してきましたが、Reduxを効果的に使うにはある程度知見が必要です。Reduxの仕組みはとてもシンプルですが、初心者にはとっつきづらい側面もあります。

Appolo ClientはReduxのようなシンプルな仕組みではありませんが、Appolo Clientを使った開発はReduxよりEasyです。各Componentが必要とする情報は、都度GraphQLのクエリを書いてレスポンスをComponentと紐付けるだけです。自分たちで状態を管理することはせず、mutationを送ってサーバ側の状態が変化したときは必要なリソースを再フェッチすることでクライントとの整合性を保ちます(最もシンプルなやり方。ほかにも方法があります)。画面部品ごとにAPIコールしていたらものすごく効率が悪そうですが、そこはAppolo Clientが内部でキャッシュを持っており、キャッシュがあるときはAPIコールしないという力技で解決しています。

GraphQLはRESTful APIを置き換えるか

先ほどからRESTful APIとの比較をしてきましたが、GraphQLという新しい仕組みがRESTful APIに代わってWeb APIのデファクトスタンダードになるかどうかは、多くの人が関心を持つところだと思います。

GraphQLは優れた仕組みだと思いますが、私は急速には広まらないんじゃないかと感じています。理由は、GraphQLでできることは究極的にいえばRESTful APIとそんなに変わらないからです。現在もりもりと採用例が増えているgRPCはシステム間の通信方法としてRESTful APIでは出来ないことが実現できますし(具体的なことははしょります)、マイクロサービスの流行という追い風もあります。それと比べると、GraphQLは便利ではある一方で、絶対にGraphQLであるべきと言えるほどの優位性がないのが採用の動機として弱いところです。

とはいえ、私が新しくシステムを設計するとしたらGraphQLは採用したいところですし、エンジニアのクチコミで少しずつ広まっていくんじゃないかと想像しています。

まとめ

GraphQLのクエリは実用的で、ツールチェーンも優秀です。

アクセス制限/N+1対応/ロギングなど真面目に整備するとなかなか手間がかかるところもありますが、ある程度エイヤで投入できる環境であれば試してみる価値はあるんじゃないかと思います。

一緒にプロダクトを作る仲間を募っています

最後に、エンジニアとデザイナーを積極採用中です。新しい技術を取り入れるのが好きな人、価値あるプロダクトを開発したい人、オンラインフィットネスに興味がある人には魅力的な環境だと思います。興味がある方はお気軽にTwitterなどでご連絡ください。インターンや体験入社もできます。

使用している主な技術

  • Ruby on Rails
  • Kubernetes(GKE)
  • React/Redux
  • ReactNative
  • GraphQL
  • Go

--

--