GraphQL如何在子字段级别启用基于ID的查询?

GraphQL如何在子字段级别启用基于ID的查询?,graphql,graphql-js,express-graphql,Graphql,Graphql Js,Express Graphql,如果现有服务分别支持以下GraphQL查询: 查询某人的银行账户: query { balance(id: "1") { checking saving } } query { pending_order(id: "1") { books tickets } } 结果 { "data": { "balance": { "checking": "800", "saving": "

如果现有服务分别支持以下GraphQL查询:

查询某人的银行账户:

query {
    balance(id: "1") {
      checking
      saving
    }
}
query {
    pending_order(id: "1") {
      books
      tickets
    }
}
结果

{
  "data": {
    "balance": {
      "checking": "800",
      "saving": "3000"
    }
  }
}
{
  "data": {
    "pending_order": {
      "books": "5",
      "tickets": "2"
    }
  }
}
查询某人的待定订单:

query {
    balance(id: "1") {
      checking
      saving
    }
}
query {
    pending_order(id: "1") {
      books
      tickets
    }
}
结果

{
  "data": {
    "balance": {
      "checking": "800",
      "saving": "3000"
    }
  }
}
{
  "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"
    }
  }
}
如何重新构造模式,如何重用现有的查询服务

编辑(阅读丹尼尔·里尔登的答案后)

我们是否可以优化GraphQL服务,以便根据查询进行服务调用?i、 例如,如果传入的查询是

query {
    person (id: "1") {
      pending_order
    }
}
我的问题实际上变成了

person: {
  ...
  resolve: (root, { id }) => Promise.all([
    getBalance(id)
  ]) => ({ balance})
}

您必须定义一个单独的
Person
类型来包装
balance
pending\u order
字段

module.exports = new GraphQLObjectType({
  name: 'Person',
  fields: () => ({
    balance: {
      type: BalanceType,
      resolve: ({ id }) => getBalance(id)
    },
    pending_order: {
      type: OrderType,
      resolve: ({ id }) => getPendingOrders(id)
    }
  })
});
您需要在
查询中添加一个新字段
类型:

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 })
}

要让事情变得更加干涸并重用现有代码,您没有什么可做的。如果您正在寻找减少样板文件的方法,我建议。

如果查询只需要一个字段,我们可以只调用一次吗--见我的编辑上面