【iCARE Dev Meetup #20】2020年代のGraphQL Architecture を開催しました
こんにちは!iCAREの髙橋です。
4/21(水) に、オンラインにて 【iCARE Dev Meetup #20】2020年代のGraphQL Architecture を開催しました。
ご登壇したのは以下のみなさん。
Kousuke Ishikawaさん(Kotozna 株式会社技術責任者)
Yudai Shinnokiさん(WASD Inc. CTO)
qsonaさん(Quipper 所属)
私はiCAREに入社してからほぼはじめてくらいに本格的にGraphQLを使うので、楽しみにしていました。
以下、レポートをお届けします。
Kousuke Ishikawa さん
「AppSync を本番運用して 1 年: 良いところとハマったところ」
Kotozna Chatというホテル向けチャットサービスを展開しているKotoznaさん。
iOSアプリやAmplifyからGraphQLを叩いている。
AppSyncとは、AWSが提供しているGraphQLを処理するためのエンジン。
フィールドそれぞれについて個別にリゾルバを定義することもできるそうです。
AppSync・Amplifyを使ってみて。
工数削減と、既存のエンドポイントを活用する目的。
良かったところ。
ファーストリリースまでのリードタイム削減できたこと。
苦労したところ。
バックエンドの開発環境構築が大変になった。
データソースをRDS+HTTPにしたところが大きい。
動作確認が大変。
スキーマが大きくなると生成に時間がかかった。
ネストしたリゾルバを実行した際に、Rate Limitに引っかかった。
RateLimitに引っかかるので、同時に実行している他のクエリも巻き添えに。
どんなフレームワークを使うにしても、内部で使われてる技術にちゃんと向き合おう。という教訓。
AppSyncを使うときは、データソースはLambdaとDynamoDBの組み合わせがいいんじゃないか。
Yudai Shinnoki さん
「組織戦略と GraphQL、Hasura」
https://speakerdeck.com/shinnoki/zu-zhi-zhan-lue-to-graphql-hasura
GraphQL Asia 2021でスピーカーされたしんのきさん。
WASD社では、接客をDXするサービスを展開していて、その中でGraphQLとHasuraを採用しているそうです。
その他の技術スタックは、React/ReactNativeなど。
Hasura。
知人が「便利だよ」と言っていたので名前だけ聞いたことあったんですが、詳細を知ることができました。
Hasura GraphQL Engine
PostgreSQL(サイトを見る限り、MySQLやSQL Serverからも行けそうです)テーブルから自動でCRUDのGraphQL APIを自動生成してくれるとのこと。すごい。
使い勝手はAppSyncに近いそうです。
リッチなダッシュボード、認証認可の仕組みなどいろいろ便利な機能がついています。
HasuraとGraphQL CodegenでTypeScryptコードまで生成していました。
コードを書く量が少なければ、バグも少なくなる。確かに。
発表では実際にデモをしていただきました。
ダッシュボードからリストを選択して、スキーマ作成していました。
それを、GraphiQLですぐ試せる。
TypeScriptコード生成でカラムの追加ができ、カラム削除した場合はTypeScriptの型が変わるのですぐ検知できるという理屈。
スタートアップはスピードが命。
ガッと作るけど、その後のブラッシュアップがボトルネックになりやすい。
GraphQLやHasuraを使うことで、ボトルネックを軽減できる。
コンウェイの法則。
「ソフトウェアの構造は開発組織の構造を反映する」
初期はモノリスな密な構成をとる戦略もあり得る。
この場合、全員がフルスタックエンジニアである必要に迫られます。
専門領域をわかる方がひとりだけだと、ペアプロやレビューができないためだそうです。
No Codeツールが成熟すればそちらの方がいいけど、まだそこまでは至っていない。
ダイニーさんの事例。
https://note.com/dinii/n/n9be778bd7da3
ダイニーさんは、すごいHasuraを使いこなしている企業さんとのこと。
上記のnoteには、「バックエンドの実装工数を体感95%ほど削減できた」とあります。すごい。
発表に戻りますと、
組織戦略的観点から考えると、ピンポイントでGraphQL経験者を採用するのは難しい。
スキーマ設計から勉強しなきゃいけないのがハードル高い。
その点をHasuraを使うことによって、バックエンジニアがRDBのノウハウを生かしてやっていけるし、フロントエンドもRDBの設計を学ぶことができる、相互に歩みよることができるようになるそうです。
立ち上げ期のスタートアップとGraphQL親和性高い。
Hasuraがオススメ。ただし、ドキュメントは読む必要がある!
qsona さん
「GraphQL を利用したアーキテクチャの勘所」
https://speakerdeck.com/qsona/architecture-practices-with-graphql
Quipper社の@qsonaさんです。
GraphQLどんどん熱くなってきてるよねってことで、GraphQLを利用した設計・アーキテクチャの重要性が増してきています。
そんな中でも、既存の設計ノウハウをうまく取り入れたい一方で、GraphQLと取り合わせの悪い設計パターンは避けたいですよね、と。
GraphQLには、Web APIとしてのスキーマの側面があります。
アーキテクチャ的な側面から見ると、既存の語彙で説明すると、
クエリ=Usecase
スキーマ=Resource
と考えることができます。
Better Web APIとしての設計手法を考えたときに、Web APIの設計方法として、
Usecaseベースの設計、Resourceベースの設計の2つのアプローチが考えられます。
ユースケース(≒画面)に合わせてAPIを作る場合、問題点としては、以下のような例が挙げられます。
- 似たようなAPIが乱立しやすい
- 複数のユースケースに対応する神APIができてしまう
- 後方互換性を保つのも大変。
一方、リソースベースの設計では、アプリの仕様にあわせてAPIを作ります。
こちらにも問題点はありまして、以下の通り。
- クライアントのユースケースに合わない時がある
- 1画面で複数のリクエストが必要になったり
- 1リクエストで不要なデータを含めて取ってしまったり
qsonaさん曰く、GraphQLはリソースベースで作る方が活きるそうです。
スキーマがリソースをあらわし、クエリがユースケースをあらわす。
ユースケースを理解し、データ設計をイメージし、スキーマを考える必要があります。
クエリの自由度が高い反面、パフォーマンス低下を引き起こす可能性もあるそうです。
サーバ側で適切に対応しなければ、N+1問題が発生します。
N+1問題を回避するためには、Dataloaderパターンを適用すればよい。
リゾルバを遅延評価し、バッチで実行する仕組み。
それでも回避できないこともある。妥協も必要だそうです。
Persisted Queriesという方法もあるそうです。
クライアントが投げ得るクエリを事前にGraphQL APIサーバに登録する手法。
ユースケースをサーバサイドで管理できる。
APIの破壊的変更、廃止もスムーズにできる。
リクエストのペイロードも減らせる、GETリクエストも使えるようになる。
ここまでをまとめると、以下の通り。
- リソースベースAPIとして設計する。
- ユースケースのこともある程度理解しながら設計すると良い。
- 最適化を後回しにできる。
ここからは、GraphQL as a Service(造語)のお話。
近年、HasuraやAppSyncのような、データストアを用意するだけで簡単にGraphQL APIを提供できるサービスが登場しています。
一方、SQLじゃダメなのか、という記事も。
https://qiita.com/yancya/items/4b7979d83cbf6af9b819
HasuraやAppSyncは、リゾルバとしてデータストア呼び出し以外も選択できます。
ここでまたダイニーさんの事例が登場です。
Command - Query Separationの原則という考え方があります。
https://en.wikipedia.org/wiki/Command%E2%80%93query_separation
コマンドは何か操作を行うもの、クエリは情報を返すもの。
両方を一気にやってはいけない、という考え方です。
この考え方のもとで振り返ると、クエリのほとんどでHasuraを使える。
一方で、Mutationは特有のドメインロジックが必要になってきます。
Hasuraを使うことにより初期はHasuraのAPIを活用して実装コストを抑えることができるし、実装が複雑になってきたらRemote Schemaを活用して、ロジックをバックエンドに寄せることも可能。
将来的な拡張性も担保できます。
ますますHasura使ってみたくなりますね。
ここからは、GraphQLを用いる際に注意すべきパターンが紹介されました。
- GraphQL as BFF (Backends For Frontend)
BFFとは、フロントエンドのためのユースケースを定義する層。
GraphQLを利用すると、Queryがユースケースになる。
めんどくさいわりに身入りが少ない。
Quipperでの事例が紹介されました。
スタサプで有名ですね。
GraphQLを全面採用しており、GatewayにはSchema Stitchingを利用。
アプリ隊とWeb隊の協働により、繋ぎこみが超スムーズにいったそうです。すごい(語彙力)。
もうひとつの要注意パターンとして、クライアントサイドでのRepository パターンが紹介されました。
Usecase→Repository→Query→GraphQL API という流れになり、ドメイン層がユースケースを知っていることになって、おかしい。
Queryがユースケースを表せなくな利、GraphQLの良さが生きにくくなる。
それを回避するには、GraphQL Schemaをドメイン知識豊富なものとして、そもそも腐敗しないようにする。
サーバサイドだけでなく、ネイティブエンジニアも積極的にスキーマ設計に関わると良い。
どなたの発表もとても勉強になりました!!中身の濃ゆーい勉強会でしたね!!
iCAREでは、ともにGraphQLを使ってスキーマ駆動開発をしていただける仲間をフロントエンド・サーバサイドとも大大絶賛採用中です!
We are Hiring!!!