我不知道如何命名这个问题,但这是我不确定的。
我有一个React前端,它对我们的GraphQl中间层进行GraphQl查询,通过调用遗留的REST来聚合数据。
例如,在React中,我可以调用getCustomer查询:
query getCustomer($id: Int!) {
getCustomer(id: $id) {
name
email
}
}它将击中getCustomer解析器,然后该解析器向REST customers/{id}端点发出请求,以返回数据。
async function getCustomer(_, { id }, ctx) {
const customer = await ctx.models.customer.getCustomer(id);
return customer;
}如果我打印一份客户名单,这个要求是可以的。但是,我的问题是如何根据我正在查询的数据在我的解析器中提出条件API请求?
假设每个客户可以有多个地址,并且这些地址位于不同的端点上。我很想把这些地址放在我的前面:
query getCustomer($id: Int!) {
getCustomer(id: $id) {
name
email
address {
city
}
}
}如何让我的解析器基于我的types和schemas来处理这个问题?从根本上说是这样的:
async function getCustomer(_, { id }, ctx) {
const customer = await ctx.models.customer.getCustomer(id);
[If the query includes the address field]
const addresses = await ctx.models.customer.getAddressesByCustomer(id);
customer.addresses = addresses;
[/If]
return customer;
}最终,--的目标是使getCustomer解析器能够根据查询中发送的字段返回跨各个端点的所有客户数据,但如果没有请求字段,则不会发出额外的getCustomer请求。
发布于 2020-01-24 11:07:43
实际上,有两种方法可以做到这一点。第一个依赖于GraphQL如何执行请求。字段的解析器只有在以下情况下才会被调用: 1)“父”字段不为null,2)实际请求该字段。这意味着我们可以显式地为address字段提供一个解析器:
const resolvers = {
Customer: {
addresses: () => {
return ctx.models.customer.getAddressesByCustomer(id)
},
},
}通过这种方式,将为如下所示的查询调用解析器
{
query getCustomer($id: Int!) {
getCustomer(id: $id) {
name
address {
city
}
}
}
}但不会被要求
{
query getCustomer($id: Int!) {
getCustomer(id: $id) {
name
}
}
}当包装一个简单的REST时,这种方法工作得很好。但是,一些REST允许您通过可选参数请求相关资源。类似地,如果要从数据库中提取数据,则可以将其他表加入到查询中。最终的结果是在较少的往返中获得更多的数据。在本例中,您将在根级别(在getCustomer解析器中)执行所有的抓取操作。但是,您需要确定自定义实际请求的字段。为此,您将使用parse the resolve info object,这是传递给每个解析器的第四个参数。一旦确定实际请求了哪些字段,就可以对URL或SQL查询进行适当的更改。
发布于 2020-01-24 10:51:40
您的解析器应该如下所示:
const resolvers = {
Query: {
getCustomer(id) {
// return customer object
}
},
Customer: {
addresses(customer) {
// return addresses of the customer
}
}
}graphql服务器将负责调用适当的解析器。
如果要务实地定义架构,则可以定义解析器和字段定义。
https://stackoverflow.com/questions/59893717
复制相似问题