graphql/type
模块的职责为定义 GraphQL 的类型和 schema。你可以从 graphql/type
模块或是根模块 graphql
引入。例如:
import { GraphQLSchema } from 'graphql'; // ES6 var { GraphQLSchema } = require('graphql'); // CommonJS
Schema
定义(Definitions)
class GraphQLScalarTypeGraphQL 中表示标量的类型。
class GraphQLObjectTypeGraphQL 中包含字段的对象类型。
class GraphQLInterfaceTypeGraphQL 中的接口类型,定义了实现该接口需要持有的字段。
class GraphQLUnionTypeGraphQL 中的联合类型,定义一系列有效类型的合集。
class GraphQLEnumTypeGraphQL 中的枚举类型,定义一系列有效值的合集。
class GraphQLInputObjectTypeGraphQL 中的输入对象类型,表示一系列结构化的输入参数。
class GraphQLList类型包装器,表示被包装类型的列表。
class GraphQLNonNull类型包装器,表示被包装类型取值非空的版本。
谓词函数(Predicates)
去包装修饰器(Un-modifiers)
标量类型(Scalars)
class GraphQLSchema { constructor(config: GraphQLSchemaConfig) } type GraphQLSchemaConfig = { query: GraphQLObjectType; mutation?: ?GraphQLObjectType; }
使用指定的 query 及 mutation(可选)的根类型来创建 Schema。生成的 Schema 可用于之后的验证器和执行器。
var MyAppSchema = new GraphQLSchema({ query: MyAppQueryRootType mutation: MyAppMutationRootType });
class GraphQLScalarType<InternalType> { constructor(config: GraphQLScalarTypeConfig<InternalType>) } type GraphQLScalarTypeConfig<InternalType> = { name: string; description?: ?string; serialize: (value: mixed) => ?InternalType; parseValue?: (value: mixed) => ?InternalType; parseLiteral?: (valueAST: Value) => ?InternalType; }
所有请求的叶节点值和输入值都必须是标量(或枚举)类型。构建标量类型 GraphQLScalarType
时,需要指定 name
以及一系列用于确保值的有效性的序列化函数。
var OddType = new GraphQLScalarType({ name: 'Odd', serialize: oddValue, parseValue: oddValue, parseLiteral(ast) { if (ast.kind === Kind.INT) { return oddValue(parseInt(ast.value, 10)); } return null; } }); function oddValue(value) { return value % 2 === 1 ? value : null; }
class GraphQLObjectType { constructor(config: GraphQLObjectTypeConfig) } type GraphQLObjectTypeConfig = { name: string; interfaces?: GraphQLInterfacesThunk | Array<GraphQLInterfaceType>; fields: GraphQLFieldConfigMapThunk | GraphQLFieldConfigMap; isTypeOf?: (value: any, info?: GraphQLResolveInfo) => boolean; description?: ?string } type GraphQLInterfacesThunk = () => Array<GraphQLInterfaceType>; type GraphQLFieldConfigMapThunk = () => GraphQLFieldConfigMap; // 关于解析器函数,请参见下文 type GraphQLFieldResolveFn = ( source?: any, args?: {[argName: string]: any}, context?: any, info?: GraphQLResolveInfo ) => any type GraphQLResolveInfo = { fieldName: string, fieldNodes: Array<Field>, returnType: GraphQLOutputType, parentType: GraphQLCompositeType, schema: GraphQLSchema, fragments: { [fragmentName: string]: FragmentDefinition }, rootValue: any, operation: OperationDefinition, variableValues: { [variableName: string]: any }, } type GraphQLFieldConfig = { type: GraphQLOutputType; args?: GraphQLFieldConfigArgumentMap; resolve?: GraphQLFieldResolveFn; deprecationReason?: string; description?: ?string; } type GraphQLFieldConfigArgumentMap = { [argName: string]: GraphQLArgumentConfig; }; type GraphQLArgumentConfig = { type: GraphQLInputType; defaultValue?: any; description?: ?string; } type GraphQLFieldConfigMap = { [fieldName: string]: GraphQLFieldConfig; };
几乎所有你要去定义的 GraphQL 类型都会是 Object 类型。Object 类型有自己的名字 name
,但最重要的是它描述了它有哪些字段。
当两个类型需要相互指代,或是某类型的某一字段类型为其自身,你可以使用函数表达式(也可称为闭包或是 thunk)来实现字段类型的延后求值。
注意,解析器函数提供 source
对象作为第一个参数。但是,如果未提供解析器函数,则将在 source
中查找与该字段名称相同的方法来作为默认的解析器。如果找到,则使用 (args, context, info)
调用该方法。由于它是一个在 source
上的方法,因此始终可以使用 this
来引用值。
var AddressType = new GraphQLObjectType({ name: 'Address', fields: { street: { type: GraphQLString }, number: { type: GraphQLInt }, formatted: { type: GraphQLString, resolve(obj) { return obj.number + ' ' + obj.street } } } }); var PersonType = new GraphQLObjectType({ name: 'Person', fields: () => ({ name: { type: GraphQLString }, bestFriend: { type: PersonType }, }) });
class GraphQLInterfaceType { constructor(config: GraphQLInterfaceTypeConfig) } type GraphQLInterfaceTypeConfig = { name: string, fields: GraphQLFieldConfigMapThunk | GraphQLFieldConfigMap, resolveType?: (value: any, info?: GraphQLResolveInfo) => ?GraphQLObjectType, description?: ?string };
当一个字段可能返回多种不同类型时,可使用接口类型 GraphQLInterfaceType
,来描述所有可能类型必须有的共同字段,也可指定 resolveType
函数来决定该字段实际被解析时为何种类型。
var EntityType = new GraphQLInterfaceType({ name: 'Entity', fields: { name: { type: GraphQLString } } });
class GraphQLUnionType { constructor(config: GraphQLUnionTypeConfig) } type GraphQLUnionTypeConfig = { name: string, types: GraphQLObjectsThunk | Array<GraphQLObjectType>, resolveType?: (value: any, info?: GraphQLResolveInfo) => ?GraphQLObjectType; description?: ?string; }; type GraphQLObjectsThunk = () => Array<GraphQLObjectType>;
当一个字段可以返回多种不同类型时,可使用联合类型 GraphQLUnionType
描述所有可能类型,也可指定 resolveType
函数来决定该字段实际被解析时为何种类型。
var PetType = new GraphQLUnionType({ name: 'Pet', types: [ DogType, CatType ], resolveType(value) { if (value instanceof Dog) { return DogType; } if (value instanceof Cat) { return CatType; } } });
class GraphQLEnumType { constructor(config: GraphQLEnumTypeConfig) } type GraphQLEnumTypeConfig = { name: string; values: GraphQLEnumValueConfigMap; description?: ?string; } type GraphQLEnumValueConfigMap = { [valueName: string]: GraphQLEnumValueConfig; }; type GraphQLEnumValueConfig = { value?: any; deprecationReason?: string; description?: ?string; } type GraphQLEnumValueDefinition = { name: string; value?: any; deprecationReason?: string; description?: ?string; }
一些请求的叶节点值和输入值为枚举类型 GraphQLEnumType
。GraphQL 会将枚举值序列化为字符串,但在内部使用时,枚举值可以用任何类型来表示,一般用整型来表示。
备注:如果在定义时没有指定 value
,在内部使用时会用枚举类型的 name
作为其值。
var RGBType = new GraphQLEnumType({ name: 'RGB', values: { RED: { value: 0 }, GREEN: { value: 1 }, BLUE: { value: 2 } } });
class GraphQLInputObjectType { constructor(config: GraphQLInputObjectConfig) } type GraphQLInputObjectConfig = { name: string; fields: GraphQLInputObjectConfigFieldMapThunk | GraphQLInputObjectConfigFieldMap; description?: ?string; } type GraphQLInputObjectConfigFieldMapThunk = () => GraphQLInputObjectConfigFieldMap; type GraphQLInputObjectFieldConfig = { type: GraphQLInputType; defaultValue?: any; description?: ?string; } type GraphQLInputObjectConfigFieldMap = { [fieldName: string]: GraphQLInputObjectFieldConfig; }; type GraphQLInputObjectField = { name: string; type: GraphQLInputType; defaultValue?: any; description?: ?string; } type GraphQLInputObjectFieldMap = { [fieldName: string]: GraphQLInputObjectField; };
一个输入对象类型定义了一组可以作为某字段查询参数的字段。
使用 NonNull
确保查询一定会有返回值。
var GeoPoint = new GraphQLInputObjectType({ name: 'GeoPoint', fields: { lat: { type: new GraphQLNonNull(GraphQLFloat) }, lon: { type: new GraphQLNonNull(GraphQLFloat) }, alt: { type: GraphQLFloat, defaultValue: 0 }, } });
class GraphQLList { constructor(type: GraphQLType) }
列表类型是一种类型标记,用来包装另一个类型。在定义一个对象类型的字段时,经常出现。
var PersonType = new GraphQLObjectType({ name: 'Person', fields: () => ({ parents: { type: new GraphQLList(PersonType) }, children: { type: new GraphQLList(PersonType) }, }) });
class GraphQLNonNull { constructor(type: GraphQLType) }
非空(non-null)类型是一种类型标记,用来包装另一个类型。强制其取值不能为 null,在某次请求时如果出现 null 值便会抛出错误。用于标记你确信肯定非空的字段时很有用,例如通常来说,数据库里某条数据的 id 字段都不会为空。
var RowType = new GraphQLObjectType({ name: 'Row', fields: () => ({ id: { type: new GraphQLNonNull(String) }, }) });
function isInputType(type: ?GraphQLType): boolean
判断某类型是否可以作为字段查询参数和指令的输入类型。
function isOutputType(type: ?GraphQLType): boolean
判断某类型是否可以作为字段查询结果值的类型。
function isLeafType(type: ?GraphQLType): boolean
判断某类型是否可以作为响应结果叶节点值的类型。
function isCompositeType(type: ?GraphQLType): boolean
判断某类型是否可以作为一个选择集的父级上下文。
function isAbstractType(type: ?GraphQLType): boolean
判断某类型是否为对象类型的组合。
function getNullableType(type: ?GraphQLType): ?GraphQLNullableType
若该类型是非空类型的包装结果,该函数会去掉包装,返回原先的类型。
function getNamedType(type: ?GraphQLType): ?GraphQLNamedType
若该类型是非空类型或列表类型的包装结果,该函数会去掉包装,返回原先的类型。
var GraphQLInt: GraphQLScalarType;
一个代表整型数的 GraphQLScalarType
。
var GraphQLFloat: GraphQLScalarType;
一个代表浮点数的 GraphQLScalarType
。
var GraphQLString: GraphQLScalarType;
一个代表字符串的 GraphQLScalarType
。
var GraphQLBoolean: GraphQLScalarType;
一个代表布尔值的 GraphQLScalarType
。
var GraphQLID: GraphQLScalarType;
一个代表 ID 值的 GraphQLScalarType
。