【書評】「初めてのGraphQL」を読んで、サーバーレスアプリケーションのための新しい武器を手に入れるのだ
2020年11月12日追記: Apollo Client V3 がリリースされ、大幅に内容がかわっています。本書のサンプル記述はV2ですので、利用法が異なる可能性があります。ご注意ください。
apollo-client/CHANGELOG.md at main · apollographql/apollo-client
きっかけは サーバーレスアプリケーションの実装で 本格的に AWS AppSync を使いたいと考えたところでした。Amplify + AppSync なチュートリアルやサンプルもたくさんありますが、要素技術を習得してから使い始めたいと考えました。私が執着している考えのひとつに、 サービスやライブラリがどこまでの責任をカバーしてくれるのかを把握してから使う があります。今回の場合だと、 AWS AppSync が GraphQL の実装サービスとして、どこまでやってくれるのかをまず知りたいと思いました。
そこで、入門書である 「初めてのGraphQL」を読みました。このエントリでは GraphQL を学びたいと思っている人向けに特長やおすすめポイントをまとめます。
著書紹介
初めてのGraphQL――Webサービスを作って学ぶ新世代API
書籍 初めてのGraphQL (以下、本書)は、Learning GraphQL の訳本で、 GraphQLというクエリ言語(正確にはクライアント/サーバー通信のための言語仕様)の入門書です。近年ではReactをはじめフロントエンドの選択肢が豊富になっており、サーバーとの通信にはより汎用的かつ効率的な方法が求められます。GraphQL はその選択肢のひとつとして、本番プロダクトでの採用実績を積み上げています。
本書ではそんな GraphQL の特長を述べつつ、Apollo という GraphQL の実装を使い、サーバーサイドは Node.js + Apollo Server で、クライアントは React + Apollo Client で実際に写真投稿アプリケーションを作っていきます。ぜひ、手を動かしながら読み進めてみてください。慣れ親しんだRESTに対して、GraphQLだとどのようにプログラミングしていくんだろう、というワクワクを感じながら楽しく学べる一冊になっています。
全体の所感、あるいはおすすめしたい人
まず大前提として、読み進めるときに 開発できる環境を準備しておくことをおすすめします。 また、本の内容に対してライブラリの進化が激しいので、そのまま転記したのでは動かない箇所がいくつかありました。そこで本のアプリケーションがすべて網羅されている GitHubリポジトリ:learning-graphql があるので、そちらも並べて進めるとよいでしょう。
本書は、リファレンス的に見る仕様集というよりは、ひとつの体系的なハンズオンドキュメントです。小難しい仕様の話もほどほどに、写真投稿アプリケーションを題材として実際にGraphQLで構築していく過程を学べます。あくまでGraphQLという技術は実装手段のひとつである、という姿勢が読み取れました。仕様を見ただけではイメージのわかない、次の具体的な例についても実装とともに解説されているのがありがたいです。
- GitHub を利用した認可
- サブスクリプションによる投稿イベントのリアルタイム通知
- React におけるGraphQL Query結果のキャッシュ
- GraphQLを通じてのファイルアップロード
参考までに、読み進めているときの画面の様子を載せておきます。
こんな人にお勧め
GraphQLという単語は聞いたことあるし興味あるけど、いまいち利用に踏ん切れない 方に刺さるはずです。主に REST API でシステムを構築している、サーバーサイド、クライアントサイドすべての開発者の方にお勧めです。また、サーバーレスでシステムを構築している・する予定がある方にも役に立ちます。
チュートリアルとの使い分けについて。GraphQLについてはオンラインにも数多くのドキュメントがありますが、たとえば GraphQL実装のひとつである Apollo のチュートリアルとの違いは何かというと、本書は
- 完全に日本語対応している
- GraphQLの仕様から体系的に学べる
- 前提知識が少なくても読める
- そもそも Apollo を知らなくても読める
- チュートリアルの前提知識として使える
という点が魅力です。本書を読んでいれば、各GraphQL実装のチュートリアルもよりスムーズに読み進められるでしょう。
目次
本書より抜粋しつつ、私の感想を添えます。
1章 GraphQL へようこそ
GraphQLの概要とWorldWideWebが登場してからGraphQLが生まれるまで の歴史的経緯を紹介します。
感想:
現在もっともメジャーな REST と比較する形で GraphQL のメリットが述べられています。「RESTだとデータの過大取得、過少取得が発生する」という共通の課題感をもつことができました。必要なものを必要な分だけ問い合わせて取得できれば、クライアントとしてはたしかに便利そうです。
2章 グラフ理論
グラフ理論の基本的な概念(ノードとエッジ、有向グラフ、グラフの一種としての木構造)を紹介します。また、現実の情報がグラフになっていて特定のノードを基準にした場合は木構造で表現できることを、Facebook のユーザー 情報を例に示します。
感想:
個人的にもっとも面白かった章です。プログラミングする中で、「一度取得したデータをもとに、別のデータを取得する」というシーンは多くあります。これはデータとデータが、グラフのようにつながっているからであり、GraphQL はその関係も含めてまるごと問い合わせができる仕様だと理解しました。実世界のデータと GraphQL で問い合わせるデータは、どちらも グラフ理論をベースにすることで関係の説明ができること に注目しており、グラフ理論が GraphQL の礎になっていることがわかりました。
3章 GraphQL の問い合わせ言語
GraphQL で実装されたAPIサーバーの使用方法について解説します。基本操作であるデータの読み込み・書き込みのほかデータのサブスクライブなど GraphQL の特徴的な仕様について解説します。データの読み込みについては 公開されている API サーバーの操作を例に解説します。
感想:
以後の章で実際にGraphQLを書いていくための事前知識集です。RESTと比べてエンドポイントが /graphql
のみ、ルート型(RESTでいう GET
や POST
のようなもの)も Query
、 Mutation
、Subscribe
だけというのはすごくシンプルです。少し気になったのは、そのぶん開発者の裁量が大きく求められることになるので、クエリの設計をどう進めるのだろう、ということでした。
4章 スキーマの設計
GraphQL APIの仕様になるスキーマの書き方について解説します。
感想:
そのような心配をしていたら、すぐ後の章で回答が用意されていました。Query
、 Mutation
、Subscribe
それぞれについて、データ型の集合である スキーマ を定義することにより、そのデザインプロセスを知ることができました。
5章 GraphQL サーバーの実装
GraphQL サーバーの実装について解説します。本書独自の実装例をもとに API サーバーを実装できるようになっています。単純な単体のデータから、一対多、多対多と順を追って複雑なデータ構造について解説し、Context の使い方、GitHub の OAuth を例に認証の実装まで一通り解説します。
感想:
ローカル環境にMongoDBを構築し、写真投稿アプリケーションの機能を実装していきます。作りたいアプリケーションが最初にあるということがとても学習効率を上げてくれ、ユースケースベースで Query
、Mutation
を使っていくのできれいに腹落ちしながら進められます。
6章 GraphQL クライアントの実装
Apollo ClientライブラリとReactを使用したGraphQLクライアントの実装を示します。読み込み、書き込みの順に解説します。書き込みについては、認証の実装を特に詳しく解説します。また、クライアント上でキャッシュを行う方法について示します。
感想:
私はもともとサーバーサイドの人間ですので、本章は 最近のクライアント開発PCパワーめっちゃ使うやん という感想が強かったです。
7章 GraphQL の実戦投入にあたって
実際のプロダクトに GraphQLを使用するための観点を述べます。サブスクライブ(リアルタイムにデータを取得し続ける機能)とファイルのアップロード、セキュリティ(現実的なデータ取得の制約)など、実運用では避けて通れない 観点について具体的な実装例を示しながら解説します。
感想:
本章はとてもうれしいものでした。実装方法だけ示して終わりというドキュメントも少なくないですが、本書は一貫して「プロダクトにGraphQLを採用する」という観点がベースにあり、本章はその締めくくりです。ファイルアップロードについて言及があったのも助かりました。
GitHub Auth を使って、写真共有アプリケーションを作る
これまでに、API の歴史について学び、クエリの実行方法について学び、スキーマを作成する方法について学びました。いよいよ充実した機能を持った GraphQL のサービスを実装できます。
感想でも述べていますが、実際に動くものを作りながら進められるハンズオンのような流れになっています。そこまで読んだ知識を総動員する形になっており、よい意味でエネルギーを使います。やってみてGraphQLのことがわかってよかった、というものあるのですが、章構成や話の持っていき方は自分がドキュメントを作るときにも参考にしたいほどでした。
スキーマファースト
スキーマファーストは設計の方法論です。スキーマファーストではアプリケーション を作成するチームメンバー全員がデータ型について理解しています。バックエンドの開発者は永続化し、リクエストに応じて返すべきデータ型を明確に理解しています。フロントエンドの開発者はユーザーインターフェースを組み立てるためにそれぞれのデータ型の定義を理解しています。スキーマファーストではすべてのチームメンバーがデータ型を共通言語にして開発にまつわるコミュニュケーションを取ることができます。
この話を見て、もしかしたらGraphQLは サーバーレスアプリケーションと相性がよいかもしれない と考えました。サーバーレスアプリケーションは「必要なユースケース」に対し、サービスやFunctionを組み合わせてソリューションを実現するパラダイムです。ゆえに、まずは課題を出し、それを解決するユースケースを決めるところから始まります。REST API の場合はリソースに対する操作がベースとなっているので、DB設計が固まれば実装を始められます。このとき、利用するDBによっては、ユースケースが定まった後のほうが設計精度を上げられます。DynamoDBはその代表格ですね。
DynamoDB では、最も一般的で重要なクエリをできるだけ速く、安価にするために、具体的にスキーマを設計します。データ構造は、ビジネスユースケースの特定の要件に合わせて調整されています。 DynamoDB に合わせた NoSQL 設計 - Amazon DynamoDB https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/bp-general-nosql-design.html#bp-general-nosql-design-approach
これはGraphQLの設計方針と一致しています。アプリケーションの設計を同じタイミングでしかけられるのは、効率がよく開発者にとってうれしいことです。
クライアント(React App)のキャッシュ
開発者として、常にネットワークリクエストは最小化したいものです。ユーザーに無意味なリクエストをさせることは避けるべきでしょう。ここではアプリが送信するネッ トワークリクエストの回数を最小化するために、Apollo Cacheをどのようにカスタマイ ズすればいいかについて詳細に見ていきます。
キャッシュは、確かに大事なことではあるのですが、最初、なぜGraphQLの話でキャッシュが強調されるのか疑問でした。読んでいくうちに解消され、 クライアントアプリにおけるキャッシュは、そのまま状態管理方法に直結するから だとわかりました。実際、 Apollo Client vs Redux で (同軸で語るべきではないとまえがきしたうえで)比較されている方もいらっしゃいます。
- Apollo Clientは便利だけど、考えるのが楽しいのはRedux|seya|note
- React Apollo vs Redux + REST: Implementing the same feature twice
「役割が全然違うやん」と思っていたのですが、 Apollo Client は GraphQL のクエリ構造とキャッシュ構造を一致させられることに注目し、ライブラリの中で自動的にクエリ結果をキャッシュしてくれます。それをコンポーネントの状態としてバインディングしておけば、React Component の状態管理ができる、という理屈です。このあたりはもう少しクライアントアプリケーションの実装を繰り返した後に再度議論したいです。ただ少なくとも、状態管理も含めて Apollo Client で完結させる選択肢があるとわかったのは収穫でした。
まとめ
本書の React アプリケーションはクラスベースコンポーネントで記載されていますが、私はせっかくなので @apollo/react-hooks の useQuery
や useMutation
を利用して実装を進めました。 これは料理界ではレシピを勝手にアレンジするというメシマズへつながる禁忌 ですのでマネしないでください。とはいえ、詰まって時間がかかったことを除けば、React Hooks による GraphQL の使い方も学べたので大きな収穫でした。
本命は AppSync で、本書を読んだのはその土台を知ることが目的でしたが、Apollo をはじめ多くのエコシステムを知ることができました。値段以上の価値です。GraphQLを採用しようかどうか悩んでいる方は、ぜひ手にとって見てください。今後は AppSync に踏み入れていきます。