如果这是一个愚蠢的问题,请道歉。这是继电器/ graphql分页的代码让我很困惑:
const GraphQLTodo = new GraphQLObjectType({
name: 'Todo',
fields: {
id: globalIdField('Todo'),
text: {
type: GraphQLString,
resolve: (obj) => obj.text,
},
complete: {
type: GraphQLBoolean,
resolve: (obj) => obj.complete,
},
},
interfaces: [nodeInterface],
});
/* When pagination is needed, make a connection */
const {
connectionType: TodosConnection,
edgeType: GraphQLTodoEdge,
} = connectionDefinitions({
name: 'Todo',
nodeType: GraphQLTodo,
});
const GraphQLUser = new GraphQLObjectType({
name: 'User',
fields: {
id: globalIdField('User'),
todos: {
type: TodosConnection,
args: {
status: {
type: GraphQLString,
defaultValue: 'any',
},
...connectionArgs,
},
resolve: (obj, {status, ...args}) =>
connectionFromArray(getTodos(status), args),
},
totalCount: {
type: GraphQLInt,
resolve: () => getTodos().length,
},
completedCount: {
type: GraphQLInt,
resolve: () => getTodos('completed').length,
},
},
interfaces: [nodeInterface],
});
const Root = new GraphQLObjectType({
name: 'Root',
fields: {
viewer: {
type: GraphQLUser,
resolve: () => getViewer(),
},
node: nodeField,
},
});
你可以看到在GraphQLTodo字段上,它有文本和完整字段,解析函数传递了一个obj参数,obj是如何传递给那里的?是从GraphQLUser解决?我已经阅读了源文件(在本例中为obj) - 从父类型字段解析的对象。它不是来自根查询? obj如何创建?
答案 0 :(得分:2)
这是魔法发生的地方(
)const {
connectionType: TodosConnection,
edgeType: GraphQLTodoEdge,
} = connectionDefinitions({
name: 'Todo',
nodeType: GraphQLTodo,
});
您现在告诉GraphQL,TodosConnection
将由GraphQLTodo
个节点组成。现在,让我们来看看GraphQLUser
字段中todos
对象中为连接实际提取对象的位置:
todos: {
type: TodosConnection,
args: {
status: {
type: GraphQLString,
defaultValue: 'any',
},
...connectionArgs,
},
resolve: (obj, {status, ...args}) =>
connectionFromArray(getTodos(status), args),
},
那么对象来自哪里?这里的关键部分是getTodos
函数,它负责从数据源中实际获取对象数组。由于此字段为TodosConnection
,并且我们已在连接定义中指定节点为GraphQLTodo
,因此GraphQL知道text
和complete
字段是通过获取(在这种情况下)已返回的对象上具有相同名称的字段来解决。换句话说,返回的对象将传递给每个字段上的resolve
方法。
Root
上有两个字段:viewer
和node
。暂时忽略node
,您只有一种实际查询待办事项的方法。由于viewer
的类型为GraphQLUser
,而GraphQLUser
具有todos
字段,因此只能将其作为viewer
的子字段提取,如下所示:
{
viewer {
todos(first: 10) {
edges {
# each node is a Todo item
node {
text
complete
}
}
}
}
}
但那个node
字段怎么样? Relay希望能够使用顶级查询获取任何对象,即在Root
字段上,当给定唯一globalId
时,它只是类型名称和id的base64编码,因此Todo:1
被编码为VG9kbzox
。这是在nodeDefinitions
中设置的(您没有包含在此处,但可能已包含在内)。在这些定义中,globalId
被解析回type
(Todo
)和id
(1
),然后再次告诉它如何从数据源中获取正确的对象。它可能看起来像:
const { nodeInterface, nodeField } = nodeDefinitions(
(globalId) => {
const { type, id } = fromGlobalId(globalId);
if (type === 'Todo') {
return getTodo(id)
} else if (type === 'User') {
return getUser(id)
}
...
由于您在nodeInterface
和GraphQLTodo
类型中实施了GraphQLUser
,因此Relay可以从Root
&#查询其中任何一种39; s node
字段。