GraphQL.js
GraphQL.js は、GraphQL の JavaScript 実装。多くの JavaScript/TypeScript の GraphQL 支援ライブラリ (graphql-tools, graphene-js) のベースとなっている。 これらライブラリや Apollo Server 等のサーバ実装についても、それらを利用するのであれば必ず GraphQL.js に触れることになる。そして、そのコアとなるのが GraphQLSchema オブジェクトである。 GraphQLSchema オブジェクトは、主に以下の2つのコンポーネントから構成される。
スキーマ定義 GraphQL サーバーにおける 構造
リゾルバー実装 GraphQL サーバーにおける 振る舞い
実際に GraphQLSchema オブジェクトを作成すると、以下のようになる。スキーマ定義は GraphQLObject として定義できる。リゾルバ定義は、その中でフィールド定義に紐づけて追加できる。
code:js
const Item = new GraphQLObjectType({
name: 'Item',
fields: {
id: { type: GrpahQLID },
name: { type: GraphQLString }
}
})
const schema = new GraphQLSchema({
query: new GraphQLObjectType({
name: 'Query',
fields: {
item: {
type: Item,
args: {
id: { type: GraphQLID }
},
resolve: (root, args, context, info) => {
const { id } = args;
return fetchItemById(id)
}
}
}
})
})
主な機能
parse, buildASTSchema GraphQL の SDL 文字列を GraphQLSchema オブジェクトに変換する
validate GraphQLSchema とクエリが与えられた時、クエリが GraphQLSchema 定義に沿っているかを検証する
excute GraphQLSchema とクエリが与えられた時、対応するリゾルバーを実行しレスポンスを返す
printSchema GraphQLSchema オブジェクトを SDL 文字列に変換する
graphql は、GraphQLSchema インスタンスとクエリを引数に取り、validate と execute を実行する。graphql は、フィールド毎のリゾルバの実行制御と、その結果の集約 & 整形を担う。そのため、graphql 関数は GraphQL engine として参照されることもある。
code:js
graphql(schema, query).then(result => console.log(result))
API リファレンス
API リファレンスをかいつまんでみる。型定義のリファレンスは以下にあるので、以下を参照すれば公開されている API が大体わかる。既述の通り、コアとなるのは GraphQLSchema オブジェクトであり、さらにはそこに受け渡される基本的な単位である GraphQLObject である。これらの2つについて詳しく見てみる。
GraphQLSchema
GraphQLSchema オブジェクトの型定義は以下のようになる。query と mutation になる GraphQLObject を与えて初期化する。GraphQLObject クラスについては後述する。
code:ts
class GraphQLSchema {
constructor(config: GraphQLSchemaConfig)
}
type GraphQLSchemaConfig = {
query: GraphQLObjectType;
mutation?: ?GraphQLObjectType;
}
GraphQLObject
GraphQLObject は、GraphQL.js において、ほとんど全ての型を表現するのに利用される。あまり深く考えず雑に移してきているためミスがあるかもしれないし、厳密にはオブジェクトの形式に沿っていない部分もあるが、GraphQLObject の型定義をオブジェクトの形に直すと以下のようになる。フィールド定義とリゾルバ定義を保持することができるようになっており、リゾルバ定義はフィールド定義に紐づいている。 code:js
{
name: <string>,
interfaces: [
{
<FieldName>: {
type: GraphQLOutputType;
args?: {
<ArgName>: {
type: <GraphQLInputType>.
defaultValue: <any>,
description: <string>
},
...
}
resolve: resolve: (
source: <any>,
context: <any>,
info: {
fieldName: string,
fieldNodes: Array<Field>,
returnType: GraphQLOutputType,
parentType: GraphQLCompositeType,
schema: GraphQLSchema,
rootValue: any,
operation: OperationDefinition,
}
) => any,
deprecationReason: <string>,
description: <string>
}
},
...
],
fields: {
<FieldName>: {
type: GraphQLOutputType,
args: {
<ArgName>: {
type: <GraphQLInputType>.
defaultValue: <any>,
description: <string>
},
...
}
resolve: (
source: <any>,
context: <any>,
info: {
fieldName: string,
fieldNodes: Array<Field>,
returnType: GraphQLOutputType,
parentType: GraphQLCompositeType,
schema: GraphQLSchema,
rootValue: any,
operation: OperationDefinition,
}
) => any,
deprecationReason: <string>,
description: <string>
},
...
},
istypeOf: ...,
description: <string>
}