はじめに
先日に引き続きGraphQLを一から勉強し直していきます。
前回はこちら。
リゾルバ
スキーマで定義された型に基づいてデータを取得するための関数。クエリが実行されると、各フィールドに対応するリゾルバが呼び出され、データベースや他のAPIから必要なデータを取得して返す。
フィールドリゾルバ
フィールドの型がスカラーの場合実行は完了するが、オブジェクト型の場合はそのオブジェクトに属するフィールドがスカラー型または列挙型になるまで実行を繰り返す。
type Query {
human(id: ID!): Human
}
type Human {
name: String
appearsIn: [Episode]
starships: [Starship]
}
enum Episode {
NEWHOPE
EMPIRE
JEDI
}
type Starship {
name: String
}
query {
human(id: 1002) {
name
appearsIn
starships {
name
}
}
}
{
"data": {
"human": {
"name": "Han Solo",
"appearsIn": [
"NEWHOPE",
"EMPIRE",
"JEDI"
],
"starships": [
{
"name": "Millenium Falcon"
},
{
"name": "Imperial shuttle"
}
]
}
}
}
具体的にどのようにresponseを返すのかを見ていく。(以降はJavaScriptの例)
ルートフィールドとリゾルバ
-
obj
: 直前のオブジェクト(ルート・クエリ型のフィールドの場合、この引数は使用されないことが多い) -
args
: GraphQL操作でフィールドに提供される引数 -
context
: すべてのリゾルバに提供される値で、現在ログインしているユーザーやデータベースへのアクセスのような重要なコンテキスト情報を保持している可能性がある -
info
: 一般的に高度な使用例でのみ使用され、スキーマの詳細と同様に現在の操作に関連するフィールド固有の情報を保持する値(https://graphql.org/graphql-js/type/#graphqlobjecttype)
function Query_human(obj, args, context, info) {
return context.db.loadHumanByID(args.id).then(
userData => new Human(userData)
)
}
非同期リゾルバ
context
はデータベースからデータを取得するが、データ取得は非同期操作でPromiseを返す。リゾルバ関数はPromiseを扱うがクエリ自体はその詳細を気にしないため、Promiseが完了するのを待ち、最適な並行性で処理を続ける。
簡単なリゾルバ
通常はオブジェクトのプロパティをそのまま返す。
多くのGraphQLライブラリではこのようなリゾルバを省略できる。つまり、以下を明示的に定義しなくてもGraphQLライブラリが自動的に処理してくれる。
function Human_name(obj, args, context, info) {
return obj.name
}
スカラー強制
GraphQLがリゾルバから返された値をスキーマで定義された型に自動的に変換するプロセス。
リストリゾルバ
GraphQLフィールドがリスト(配列)を返す場合に使用されるリゾルバ関数。
各リスト要素に対して個別にデータを取得し、非同期処理を行う。GraphQLはPromiseがすべて解決されるのを待ち、並行して処理を続ける。
参考