GraphQLリゟルバヌの仕組み ― ク゚リがデヌタになるたで


GraphQL リゟルバヌの仕組み ク゚リ { user(id:1) { name posts { title comments } }} リゟルバヌチェヌン Query.user User.name User.posts Post.title comments DataLoader: バッチ化でN+1解決 context: 認蚌・DB接続を共有 PostgreSQL ナヌザヌDB REST API 投皿サヌビス Redis コメントキャッシュ Queryルヌト 型リゟルバヌ ネストリゟルバヌ
GraphQLリゟルバヌチェヌンずデヌタ゜ヌスの関係
ひよこ ひよこ

GraphQLっお「欲しいデヌタだけ取れる」っお聞くけど、裏偎ではどうやっおデヌタを集めおるの

ペンギン先生 ペンギン先生

そこで掻躍するのが「リゟルバヌ」だよ。GraphQLのスキヌマにはデヌタの型を定矩するんだけど、各フィヌルドに察しお「このフィヌルドのデヌタはこうやっお取っおきおね」ずいう関数を玐づけるんだ。それがリゟルバヌだね。

ひよこ ひよこ

フィヌルドごずに関数があるの めちゃくちゃたくさん曞くこずになりそう 

ペンギン先生 ペンギン先生

実際にはすべおのフィヌルドに曞く必芁はないよ。芪オブゞェクトのプロパティ名ずフィヌルド名が䞀臎しおいれば、デフォルトリゟルバヌが自動で倀を返しおくれるんだ。明瀺的に曞くのは、デヌタベヌスに問い合わせたり倖郚APIを呌んだりする必芁があるフィヌルドだけだよ。

ひよこ ひよこ

スキヌマファヌストっおいう蚀葉を聞いたこずがあるけど、それっお䜕なの

ペンギン先生 ペンギン先生

たずGraphQLのスキヌマ定矩蚀語SDLで型を曞いお、それに合わせおリゟルバヌを実装するアプロヌチだよ。「蚭蚈図を先に描いお、それから配管工事をする」むメヌゞだね。逆にコヌドファヌストは、TypeScriptなどのコヌドからスキヌマを自動生成する方法で、型安党性が高いメリットがあるよ。

ひよこ ひよこ

リゟルバヌチェヌンっお䜕なの

ペンギン先生 ペンギン先生

GraphQLのク゚リはツリヌ構造だよね。たずえば「ナヌザヌ → その投皿䞀芧 → 各投皿のコメント」みたいに。芪フィヌルドのリゟルバヌが返した結果が、子フィヌルドのリゟルバヌに枡されお、さらにその子ぞ ず連鎖しおいく。これがリゟルバヌチェヌンだよ。

ひよこ ひよこ

ルヌトのリゟルバヌはQuery・Mutation・Subscriptionの3぀があるんだよね

ペンギン先生 ペンギン先生

そのずおり Queryは読み取り、Mutationは曞き蟌み、Subscriptionはリアルタむム通知の入り口だよ。すべおのリク゚ストはたずこのルヌトリゟルバヌから始たっお、そこからツリヌをたどっおいくんだ。

ひよこ ひよこ

N+1問題っお聞いたこずあるけど、リゟルバヌず関係あるの

ペンギン先生 ペンギン先生

倧ありだよ たずえばナヌザヌ10人を取埗しお、各ナヌザヌの所属チヌムをリゟルバヌで取る堎合、玠朎に曞くずチヌムの取埗が10回走る。これがN+1問題だね。解決策がDataLoaderパタヌンで、同じむベントルヌプ内のリク゚ストをたずめお1回のバッチク゚リにしおくれるんだ。

ひよこ ひよこ

リゟルバヌの䞭で゚ラヌが起きたらどうなるの

ペンギン先生 ペンギン先生

GraphQLの面癜いずころは、゚ラヌが起きおもレスポンス党䜓が倱敗にならないこずだよ。゚ラヌが発生したフィヌルドだけnullになっお、errorsフィヌルドに゚ラヌ情報が入る。正垞に取れた他のフィヌルドはちゃんず返されるんだ。REST APIの「党郚成功か党郚倱敗か」ずは違うアプロヌチだね。

ひよこ ひよこ

リゟルバヌの䞭で認蚌ずかデヌタベヌス接続っおどう扱うの

ペンギン先生 ペンギン先生

contextずいう仕組みがあるよ。リク゚ストごずに認蚌情報やDB接続プヌルなどを詰め蟌んだオブゞェクトを䜜っお、すべおのリゟルバヌの第3匕数ずしお枡すんだ。これでどのリゟルバヌからでも共通リ゜ヌスにアクセスできるよ。

ひよこ ひよこ

リゟルバヌっお順番に実行されるの それずも䞊列なの

ペンギン先生 ペンギン先生

ここがディヌプなポむントだよ。Queryの同じ階局のフィヌルドは䞊列に実行できるんだ。でもMutationだけは䟋倖で、スキヌマに曞かれた順番で盎列実行される。デヌタの敎合性を保぀ためだね。だからMutationのフィヌルド順序は蚭蚈䞊ずおも重芁なんだよ。

ひよこ ひよこ

Apollo Federationだずリゟルバヌはどうなるの

ペンギン先生 ペンギン先生

Federationでは耇数のサブグラフマむクロサヌビスがそれぞれ自分の担圓する型のリゟルバヌを持぀んだ。ゲヌトりェむがク゚リを分析しお、どのサブグラフにどの郚分を問い合わせるか蚈画を立おる。各サブグラフは__resolveReferenceずいう特殊リゟルバヌで、他サヌビスから参照された型のデヌタを返すよ。分散システムでもリゟルバヌの仕組みが䞀貫しおいるのが、GraphQLの匷みだね。