当然,这是 GraphQL 服务器中两个突变的示例。我们可以分解它以了解发生了什么。
首先让我们看一下类型系统。一个 GraphQL 模式通常有两个根字段 query 和 mutation(有时还有 subscription)。这些根字段是您的数据层次结构的根,并公开您有权访问的查询(GET 请求)和突变(POST、PUT、DELETE 等请求)。
从外观上看,您正在实现一个具有如下所示的根突变类型的架构:
type Mutation {
createAuthor: Author
createPost: Post
}
GraphQL 中的类型由一组字段组成,每个字段都可以有一个关联的解析器。 GraphQL 中的解析器就像您将附加到 REST 中的端点的事件处理程序。
您上面的代码定义了两个解析器,它们将处理与createAuthor 和createPost 突变相关的逻辑。 IE。 createPost 解析器中的代码是当我发出这样的查询时将运行的代码:
mutation CreatePost($post: CreatePostInput!) {
createPost(input: $post) {
id
title
tags
text
}
}
GraphQL 运行时解析查询并根据查询的内容将操作路由到正确的解析器。在此示例中,它会看到我正在调用 createPost 突变,并确保调用 createPost 解析器,在您的情况下看起来像这样:
createPost: (root, { authorId, tags, title, text }) => {
return Author.findOne({ where: { id: authorId } }).then( (author) => {
console.log('found', author);
return author.createPost( { tags: tags.join(','), title, text });
});
},
要了解解析器的工作原理,让我们看一下 graphql-js
中的
GraphQLFieldResovler 类型定义
export type GraphQLFieldResolver<TSource, TContext> = (
source: TSource,
args: { [argName: string]: any },
context: TContext,
info: GraphQLResolveInfo
) => mixed;
如您所见,GraphQLFieldResolver 是一个接受 4 个参数的函数。
-
来源:来源是当前字段的父对象。例如,如果您为
User 类型的字段 fullName 定义解析器,则源将是完整的用户对象。
-
args:args 是该解析器的任何输入参数。在我上面的查询中,它将包含
$post 变量的值。
-
上下文:上下文是 GraphQL 执行的全局上下文。这对于传递解析器可能需要的信息很有用。例如,您可以在解析器中包含一个数据库连接,而无需在每个文件中都导入它。
-
info:info 对象包含有关您的 GraphQL 架构、查询和其他信息的信息,例如当前正在执行的解析器的路径。这在很多方面都很有用。这是一篇讨论如何使用它来预计算查询的帖子:(https://scaphold.io/community/blog/querying-relational-data-with-graphql/)
拥有类型和字段解析器的想法是 GraphQL 如此强大的部分原因。一旦您定义了类型系统及其字段的解析器,您就可以根据需要构建架构,无论查询嵌套多深,GraphQL 都将始终确保调用正确的解析器。
我希望这会有所帮助:)