【问题标题】:How can GraphQL enable an ID based query at sub fields level?GraphQL 如何在子字段级别启用基于 ID 的查询?
【发布时间】:2018-07-01 22:37:15
【问题描述】:

如果现有服务分别支持以下 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"
    }
  }
}

如何重新构建架构,如何重用现有的查询服务?

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

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

query {
    person (id: "1") {
      pending_order
    }
}

我的实际查询变成了

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

【问题讨论】:

    标签: graphql graphql-js express-graphql


    【解决方案1】:

    您将不得不定义一个单独的 Person 类型来包装 balancepending_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

    【讨论】:

    • 如果查询只需要一个字段,我们可以只调用一次吗? --见我上面的编辑
    猜你喜欢
    • 2020-08-15
    • 2019-09-22
    • 2019-01-27
    • 2019-04-08
    • 2018-02-07
    • 2018-03-31
    • 2011-11-28
    • 1970-01-01
    • 2021-05-04
    相关资源
    最近更新 更多