GraphQL如何在子字段级别启用基于ID的查询? [英] How can GraphQL enable an ID based query at sub fields level?

查看:72
本文介绍了GraphQL如何在子字段级别启用基于ID的查询?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

If an existing service supporting the following GraphQL queries respectively:

查询某人的银行帐户:

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

实现上述功能的源代码如下:

The source code achieving the above functionality is something like this:

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服务架构支持人员级别的架构,即

Now, I want to make my GraphQL service schema support person level schema, i.e.,

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

并获得以下结果:

{
  "data": {
     "balance": {
       "checking": "800",
       "saving": "3000"
    }
    "pending_order": {
      "books": "5",
      "tickets": "2"
    }
  }
}

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

How can I re-structure the schema, and how can I reuse the existing query service?

编辑(阅读了丹尼尔·雷登的回答):

我们可以优化GraphQL服务,以便基于查询进行服务调用吗?即,如果传入查询为

Can we optimize the GraphQL service so that we make service call based upon the query? i.e., if the incoming query is

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

我的实际查询变为

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

推荐答案

您将必须定义一个单独的 Person 类型以包装 balance pending_order 字段.

You're going to have to define a separate Person type to wrap the balance and pending_order fields.

module.exports = new GraphQLObjectType({
  name: 'Person',
  fields: () => ({
    balance: {
      type: BalanceType,
      resolve: ({ id }) => getBalance(id)
    },
    pending_order: {
      type: OrderType,
      resolve: ({ id }) => getPendingOrders(id)
    }
  })
});

您将需要向 Query 类型添加一个新字段:

And you're going to need to add a new field to your Query type:

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

您没有什么能做的让事情变得更干燥并重用您现有的代码.如果您正在寻找减少样板的方法,我建议使用graphql-tools .

There's not much you can do to keep things more DRY and reuse your existing code. If you're looking for a way to reduce boilerplate, I would suggest using graphql-tools.

这篇关于GraphQL如何在子字段级别启用基于ID的查询?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆