「How to GraphQL」でチュートリアルやった
※ GraphQLについて学んだことの自分メモです。読み手に解説するものではなく、これから学ぶ人の参考になれば。
きっかけ
- React HooksとGraphQLで社内レガシーサービスを巻き取ってみたらものすごくはかどった話 - Speaker Deck (2020/01/31)
- GraphQLの全体像とWebApp開発のこれから - Qiita (2020/02/24)
- 2020年のウェブフロントエンドエンジニアが学び実践すべきこと|erukiti|note (2020/04/05)
学習前の気になるポイント
GraphQLに対する期待
レガシーシステムのモダン化手段となること。 旧式の一枚岩システムをフロント・バックで分離する手段となりうるか。
RESTの面倒が改善されること。 リソースとURLのマッピング定義、HTTPメソッドに合わせたエンドポイント制限、 パラメータ取得方法がクエリストリングやリクエストボディで分かれている、など。
HOW TO GRAPHQLとは
検索したら見つかった、ちゃんとしてる感のあるチュートリアルサイト。 作成元はPrisma。Hacker Newsのクローンが題材。1stブクマは2016年10月。
今回選択したのは以下。この2つはセットみたいなもの。
- BACKEND: graphql-node (2020/04更新)
- FRONTEND: React + Apollo (2020/02更新)
所要時間は丸3日くらい費やしたと思う。 その都度、疑問に思ったことを横道にそれながら、一つ一つ丁寧に進めてた。 あと英語だし、単語を調べながら読んでた。(たまにDeepL翻訳に投げた)
実際やってみてわかったこと
GraphQL is the better REST。 データ取得のためのQuery
、データ操作のためのMutation
をスキーマとして定義して、対応するリゾルバー関数を書く。サブスクリプションという概念もあり、それによってリアルタイム処理を実現できる。クライアントから来るクエリに柔軟性ができた分だけ後ろが複雑になる。また、ネストする注文を投げつけることで容易に攻撃ができてしまうセキュリティリスクあり。
Prisma(@1.34.10)とは、GraphQL用のORMである。 graphql-nodeチュートリアルは実質 Prisma チュートリアルだった。 スキーマ定義文書とデータモデル定義文書をインプットに、便利なリゾルバー関数をコード生成しデータベース環境までも構築する。デモ用に、MySQLをベースとしたPrisma用のデータベース環境をクラウド上に用意してくれる。
Apolloとは、GraphQLクライアントである。 チュートリアルでは React に組み込んで、事前に用意されたGraphQLサーバにQueryやMutationを発行してアプリGUIを構築する。graphql-nodeチュートリアルで作り上げたものをサーバとして使っている。リンク集のリスト表示とリンク投稿、およびデータキャッシュまわりの扱い方を学ぶことができるが、前述のようにこれだけでは不十分。BACKENDもやるべし。
RDBMSとの親和性は不明。 Prismaを使わないでGraphQLサーバを立てる手段を検証する必要がある。
認証まわりについて。考え方はRESTと同じ。ログインMutationでトークン作って返してBearerをリクエストヘッダに添えてそれ見てQueryに対応したリゾルバー関数の中で認可処理をしてる。書き方が違うだけで、やってることはRESTと一緒。
レガシーシステムのモダン化手段となるか? まだわからない。
RESTの面倒が改善されること。 一元化されたエンドポイント。パラメータの取得方法も統一。スキーマ定義言語によるサーバーとクライアント間の契約から始まる設計は良いと思った。
Prisma開発の流れ理解
datamodel.prisma
でモデル=DBテーブルを定義- マシングローバルにインストールした prisma コマンドでデータモデル定義からCRUD的なのをジェネレート
- npmモジュール
prisma-client-lib
を使うとジェネレートしたものが使える。すべてのリゾルバー第3引数contextに差し込まれる。 - 実装は
schema.graphql
の定義から始める。これはクライアント側とサーバ側を繋ぐ契約である。 schema.graphql
に書いた定義のうち、プリミティブなもの以外はすべてリゾルバー関数として定義する必要がある。
メモ
- 発行する内容は GraphQL operation と呼ばれる。
- オペの
query
やmutation
のあとに続く文字列はオペの任意名称。- 複数のオペを書いたときに、どれがどれなのか識別するために使う。
- 実際の通信は HTTP POST で行われている
- 自分が仕事で作ってきたものは数百のテーブルとか何重にもなったビューが多いので、データモデル定義にリレーションとかやってられない。あと、Prismaはソートが1列しか指定できない。
- ORM成分高めで帰ってきたPrisma 2 - Qiita
まだよくわからないこと
graphql-yoga
の守備範囲。Prismaなしで既存DBと繋げる方法。- Apolloはクライアント側にキャッシュ機構まで提供してるけど、Reactは状態管理どうしてるの?
- クライアントアプリの状態管理までGraphQLというかサーバ側は介入するものではないような。
- Vuexに相当するものはあるのか?それとは別の、無用な通信を防ぐためのプロキシ的役割?
- Vue.jsはどうか
- AWS AppSyncとは
所感
クライアントとサーバの間にあるインターフェース定義方法が変わっただけで、それ以外は従来どおり…な気がするんだけど、結局この恩恵を最大限被るためには用意されたフレームワークを使いこなすしかない印象。 今回チュートリアルで学んだ範囲は、フロントエンド側はキャッシュ考慮、バックエンド側はテーブル定義やリレーション設計まで侵食。 これまで扱ってきたRESTを含む知識をこちらにシフトしていくために、少しずつ置換して行けるのが理想。 置換範囲が広いと手を出しにくい。
自分が普段開発に携わるもので、そのバックエンドにQueryの柔軟性が必要かと言われればそんなにいらない。 N+1問題への対処としての側面もあるが、専用のエンドポイントを用意してしまうので気にならない。実現したいGUIありきのサーバーサイドではなく、リソースを不特定多数のアプリに配信するようなサービスでないと恩恵が薄い。 特定のGUIに癒着した Web API は REST API ではないってことか。
欲しかったのは、RESTとGraphQLの中間のようなもの。 一元化されたエンドポイントと、自由に生やせるリゾルバー。 GraphQLじゃなきゃいけない理由はないけど、乗っかれるなら乗っかりたい。