GraphQL 解析器问题
Posted
技术标签:
【中文标题】GraphQL 解析器问题【英文标题】:GraphQL Resolver Problems 【发布时间】:2020-01-18 08:49:47 【问题描述】:我花了很多时间阅读 GraphQL 教程,但不幸的是,它们似乎没有涵盖足够深入的内容,让我无法理解。对于这个真实世界的例子,我真的很感激。
在示例中,查询放置在解析器对象的根目录;我可以让它对单级查询正常工作。当我尝试解析嵌套查询时,嵌套解析器永远不会被调用。令我非常困惑的是,我发现的每个教程都不是在 graphql 网站上发布的,都放在一个 Query 对象中,并将它们的查询嵌套在它之下,而不是根级别。
考虑以下架构:
type Product
id: String!
retailerId: String!
title: String!
description: String
price: String!
currency: String!
type OrderLine
product: Product!
quantity: Int!
type Order
id: String!
retailerId: String!
orderDate: Date!
orderLines: [OrderLine!]!
type Query
product(id: String!): Product
order(id: String!): Order
schema
query: Query
还有以下查询:
query
order(id: "1")
id
orderLines
quantity
我已经尝试了多个版本的解析器(现在只是测试数据),但似乎没有一个能返回我所期望的。这是我当前的解析器实现:
const resolvers =
OrderLine:
quantity: () => 1,
,
Order:
orderLines: (parent: any, args: any) => console.log("Calling order lines"); return []; ,
,
Query:
product(parent, args, ctx, other)
return id: args.id.toString(), test: true ;
,
order: ( id ) => console.log("Calling order 1"); return id: id.toString(), testOrder: true, orderLines: [] ; ,
,
order: ( id ) => console.log("Calling order 2"); return id: id.toString(), testOrder: true, orderLines: [] ; ,
;
在控制台中我可以观察到“调用订单 2”日志消息,“调用订单行”没有日志,订单行数组为空。
所以两部分的问题:
1) 为什么在上面的例子中它点击“Calling order 2”而不是“Calling order 1”?
2) 为什么上述方法不适用于嵌套查询 Order.OrderLines?
提前致谢!
【问题讨论】:
不确定是否值得注意,但该架构是使用 npm 库“graphql”中的 buildSchema 构建的。 【参考方案1】:查询中
type Query
product(id: String!): Product
order(id: String!): Order
users: User
schema
query: Query
在解析器中
const resolvers =
order: ( id ) => function
product: ( id ) => function
Graphql 致力于查询解析器的概念。如果您想要任何查询(示例用户),您必须有 解析器(即用户)返回具有用户类型定义的用户。 Graphql 查询是交互式且区分大小写的 下一步是实现订单/产品查询的解析器功能。 事实上,我们还没有提到的一件事是,不仅根字段, 但实际上 GraphQL 模式中类型的所有字段都有解析器函数。
1) 为什么在上面的例子中它点击“Calling order 2”而不是“Calling order 1”? 在这个查询中
query
order(id: "1")
id
orderLines
quantity
然后它去订单返回带有定义类型的订单
2) 为什么上述方法不适用于嵌套查询 Order.OrderLines?
You can only use two query first order and second product only as per your schema
请查看文档以了解此要求的嵌套查询。
【讨论】:
【参考方案2】:如果您使用buildSchema
生成架构,则为字段提供解析器的唯一方法是通过根对象。但这更像是一种技巧——您实际上并没有覆盖字段的默认解析器,因此,您基本上仅限于使用根级字段(因为您正在努力学习)。这就是为什么只调用Query.order
函数的原因——这是一个根级字段。详细解释了为什么通过根(种类)传递函数的工作原理here。
底线是你shouldn't be using buildSchema。如果您想使用 SDL 来定义您的架构,请迁移到使用 Apollo Server。
【讨论】:
它也不适用于 Apollo 服务器,并且表示不支持:github.com/apollographql/graphql-tools/issues/1026 @DeveloperDave 我不确定你指的是什么。在使用 Apollo Server 时,支持为任何字段提供解析器,而不仅仅是根字段,这是 OP 遇到的问题。您链接的问题仅指用于定义解析器映射的一些不受支持的语法。 不。您误解了他的问题(谷歌似乎理解它,因为除了 Github 问题线程之外,它还提到了这个 *** 问题线程)。两者都提到了在排除为什么不调用 nested 解析器时出现的挑战。昨晚我也遇到了同样的问题,我的一个查询的响应对象的“孙子”字段上的解析器没有被调用。此外,无论您是否使用 Apollo / graphql-tools 都会出现此问题(我正在使用它,该 github 问题线程上的绅士也是如此)。以上是关于GraphQL 解析器问题的主要内容,如果未能解决你的问题,请参考以下文章