GraphQL 如何在子字段级别启用基于 ID 的查询?
How can GraphQL enable an ID based query at sub fields level?
如果现有服务分别支持以下 GraphQL 查询:
查询到某人的银行账户:
query {
balance(id: "1") {
checking
saving
}
}
结果
{
"data": {
"balance": {
"checking": "800",
"saving": "3000"
}
}
}
查询到某人的挂单:
query {
pending_order(id: "1") {
books
tickets
}
}
结果
{
"data": {
"pending_order": {
"books": "5",
"tickets": "2"
}
}
}
实现上述功能的源代码是这样的:
module.exports = new GraphQLObjectType({
name: 'Query',
description: 'Queries individual fields by ID',
fields: () => ({
balance: {
type: BalanceType,
description: 'Get balance',
args: {
id: {
description: 'id of the person',
type: GraphQLString
}
},
resolve: (root, { id }) => getBalance(id)
},
pending_order: {
type: OrderType,
description: 'Get the pending orders',
args: {
id: {
description: 'id of the person',
type: GraphQLString
}
},
resolve: (root, { id }) => getPendingOrders(id)
}
})
});
现在,我想让我的 GraphQL 服务模式支持个人级别模式,即
query {
person (id: "1") {
balance
pending_order
}
}
得到如下结果:
{
"data": {
"balance": {
"checking": "800",
"saving": "3000"
}
"pending_order": {
"books": "5",
"tickets": "2"
}
}
}
如何重构架构,如何重用现有的查询服务?
编辑(阅读 Daniel Rearden 的回答后):
我们能否优化 GraphQL 服务,以便我们根据查询进行服务调用?即,如果传入查询是
query {
person (id: "1") {
pending_order
}
}
我的实际查询变成了
person: {
...
resolve: (root, { id }) => Promise.all([
getBalance(id)
]) => ({ balance})
}
您将必须定义一个单独的 Person
类型来包装 balance
和 pending_order
字段。
module.exports = new GraphQLObjectType({
name: 'Person',
fields: () => ({
balance: {
type: BalanceType,
resolve: ({ id }) => getBalance(id)
},
pending_order: {
type: OrderType,
resolve: ({ id }) => getPendingOrders(id)
}
})
});
并且您需要在 Query
类型中添加一个新字段:
person: {
type: PersonType,
args: {
id: {
type: GraphQLString
}
},
// We just need to return an object with the id, the resolvers for
// our Person type fields will do the result
resolve: (root, { id }) => ({ id })
}
要让事情变得更干并重用现有代码,您无能为力。如果您正在寻找减少样板文件的方法,我建议 using graphql-tools.
如果现有服务分别支持以下 GraphQL 查询:
查询到某人的银行账户:
query {
balance(id: "1") {
checking
saving
}
}
结果
{
"data": {
"balance": {
"checking": "800",
"saving": "3000"
}
}
}
查询到某人的挂单:
query {
pending_order(id: "1") {
books
tickets
}
}
结果
{
"data": {
"pending_order": {
"books": "5",
"tickets": "2"
}
}
}
实现上述功能的源代码是这样的:
module.exports = new GraphQLObjectType({
name: 'Query',
description: 'Queries individual fields by ID',
fields: () => ({
balance: {
type: BalanceType,
description: 'Get balance',
args: {
id: {
description: 'id of the person',
type: GraphQLString
}
},
resolve: (root, { id }) => getBalance(id)
},
pending_order: {
type: OrderType,
description: 'Get the pending orders',
args: {
id: {
description: 'id of the person',
type: GraphQLString
}
},
resolve: (root, { id }) => getPendingOrders(id)
}
})
});
现在,我想让我的 GraphQL 服务模式支持个人级别模式,即
query {
person (id: "1") {
balance
pending_order
}
}
得到如下结果:
{
"data": {
"balance": {
"checking": "800",
"saving": "3000"
}
"pending_order": {
"books": "5",
"tickets": "2"
}
}
}
如何重构架构,如何重用现有的查询服务?
编辑(阅读 Daniel Rearden 的回答后):
我们能否优化 GraphQL 服务,以便我们根据查询进行服务调用?即,如果传入查询是
query {
person (id: "1") {
pending_order
}
}
我的实际查询变成了
person: {
...
resolve: (root, { id }) => Promise.all([
getBalance(id)
]) => ({ balance})
}
您将必须定义一个单独的 Person
类型来包装 balance
和 pending_order
字段。
module.exports = new GraphQLObjectType({
name: 'Person',
fields: () => ({
balance: {
type: BalanceType,
resolve: ({ id }) => getBalance(id)
},
pending_order: {
type: OrderType,
resolve: ({ id }) => getPendingOrders(id)
}
})
});
并且您需要在 Query
类型中添加一个新字段:
person: {
type: PersonType,
args: {
id: {
type: GraphQLString
}
},
// We just need to return an object with the id, the resolvers for
// our Person type fields will do the result
resolve: (root, { id }) => ({ id })
}
要让事情变得更干并重用现有代码,您无能为力。如果您正在寻找减少样板文件的方法,我建议 using graphql-tools.