我有以下 REST 端点:
/orders/{id}
returns {
orderId,
orderItem,
customerId
}
/customers/{id}
returns {
customerId,
firstName,
lastName
}
我受限于这两个端点,它们将被包装在我的 graphql 模式中。
我想要以下架构:
type Order {
orderId: ID!,
orderItem: String,
customer: Customer
}
type Customer{
customerId: ID!
firstName: String!
lastName: String!
}
type Query {
getOrder(id: String!): Order,
getCustomer(id: String!): Customer
}
我想知道是否可以让 GraphQL 解析 Order 类型中的 Customer 对象?我了解您不能将查询结果传递给另一个查询的参数。
我认为 getOrder
的解析器是:
const getOrderResolver = axios.get(`/orders/${id}`)
.then((ordersRes) => {
let customerId;
if(ordersRes.data.customerId !== null) {
customerId = ordersRes.data.customerId
axios.get(`/customers/${customerId}`)
.then((customerRes) => ({
return {
orderId: ordersRes.data.orderId
orderItem: ordersRes.data.orderItem
customer: {
customerId: customerRes.data.customerId
firstName: customerRes.data.firstName
lastName: customerRes.data.lastName
}
}
})
} else {
return {
orderId: ordersRes.data.orderId
orderItem: ordersRes.data.orderItem
customer: null
}
}
})
})
getCustomer
解析器
const getCustomerResolver = axios.get(`/customers/${customerId}`)
.then((customerRes) => ({
return {
customerId: customerRes.data.customerId
firstName: customerRes.data.firstName
lastName: customerRes.data.lastName
}
})
在我的解决方案中,无论是否在 getOrder
查询中查询,始终获取 Customer
类型都会产生额外成本。是否可以重写我的 GraphQL 架构,使 GraphQL 仅在查询时能够解析 Customer
类型?
我给定的 ORDERS
REST API 的局限性只返回 CustomerId
使得它很难在 getOrder
中解析,因为 客户
API 需要一个customerId
最佳答案
这里有两点要记住:
- 除非请求,否则 GraphQL 不会解析字段(即,除非该字段实际包含在请求中,否则不会调用您的解析器)。
- 每个解析器都可以访问其“父”字段解析到的值。
因此您的 getOrder
解析器只能担心返回一个订单对象:
const resolvers = {
Query: {
getOrder: (parent, args, context, info) => {
const response = await axios.get(`/orders/${args.id}`)
return response.data
},
...
},
...
}
请注意,如果 REST 端点以与您的字段类型相同的“形状”返回响应,则无需在此处将响应数据映射到您的实际字段——只需返回 response.data
.
现在我们可以为订单类型的 customer
字段添加一个解析器:
const resolvers = {
Query: { ... },
Order: {
customer: (parent, args, context, info) => {
if (!parent.customerId) {
return null
}
const response = await axios.get('/customers/${parent.customerId}')
return response.data
},
},
...
}
我们的父字段是 getOrder
(或任何其他具有 Order
类型的字段)。 parent
的值将是您在该字段的解析器中返回的任何值(或者如果您返回一个 Promise,则无论 Promise 解析为什么)。因此我们可以使用 parent.customerId
来调用 /customers
端点并从响应中返回数据。同样,只有在实际请求 customer
字段时才会调用此解析器。
关于javascript - GraphQL 能否在解析器中选择性地解析给定查询结果的字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56171092/