以优雅的方式将GraphQL变量传递给第二个函数

以优雅的方式将GraphQL变量传递给第二个函数,graphql,Graphql,我正在使用GraphQL,在找到将变量从查询传递到结果的最佳方法时遇到了一些困难 我有这样一个模式: type Fragment { # The id of the fragment id: String! # The key of the fragment key: String! # The type of component component_type: String! # The params used to build the fragment params

我正在使用GraphQL,在找到将变量从查询传递到结果的最佳方法时遇到了一些困难

我有这样一个模式:

type Fragment {

# The id of the fragment

  id: String!

# The key of the fragment
  key: String!

# The type of component
  component_type: String!

# The params used to build the fragment
  params: JSON

# Component data
  data: JSON

  children: [JSON]

  items: [JSON]


}
该片段表示为“cms”片段。我想在这个问题解决后将一些查询数据传递到另一个后端

我的查询如下所示:

  query getFragmentsWithItems($keys: [String!]! 
                     $platform: PlatformType 
                     $version: String
                     $userInfo: UserInput
                     $userId: Int
                     ) {                     
    fragmentsWithItems(keys: $keys, platform: $platform, version: $version, userInfo: $userInfo, userId: $userId) {
      key
      data 
      children
      params
      items
    }
  }
问题是:我在片段的
data
字段中有一些查询数据。在解析该
片段之前,该数据不可用。我想把数据发送到另一个后端。我想用GraphQL来做这件事,我希望做一些类似的事情:

Fragment: () => {
  async query(obj, args, context, info, {modles}) => {
    const items = await models.getItems(obj.query_string);
  }
}
type Fragment {
items: ItemSearchResult(user_info: UserInput) etc
但是我需要传递给原始查询的
user\u info
user\u id
。显然,这只能从
info
参数中访问,而该参数并不打算使用

我采用的另一种方法是使用手动解析器,它可以执行以下操作:

const resolveFI = ({ keys, platform, version, userInfo, userId, models }) => {
  if (!keys || !keys.length) {
    return Promise.resolve(null);
  }
  return models.release.get({ platform, version }).then(release =>
    Promise.all(
      keys.map(key =>
        models.fragments.get({
          key,
          platform,
          version,
          release: release.id
        })
      )
    ).then(data => {
      const promises = [];
      data.rows.forEach(r => {
        if (r.data.query_data) {
          const d = {
            // Can just ignore
            filters: r.data.query_data.filters || {},
            user_info: userInfo,
            user_id: userId
          };
          promises.push(
            new Promise(resolve => {
              resolve(
                models.itemSearch.get(d).then(i => ({ items: i.items, ...r }))
              );
            })
          );
        }
        ...etc other backends 
这是可行的,但是手动承诺链似乎无法达到使用GraphQL的目的

我最后尝试的是将
设置为非标量类型,类似于:

Fragment: () => {
  async query(obj, args, context, info, {modles}) => {
    const items = await models.getItems(obj.query_string);
  }
}
type Fragment {
items: ItemSearchResult(user_info: UserInput) etc
但由于我无法将实际结果从片段传输到无法工作的ItemSearchResult

我意识到这相当冗长,所以我愿意接受编辑或澄清。

我想看看我是否错过了一个更好的方法,或者我是否应该把它打包,让客户端应用程序在取回片段数据后进行项目查询。

这并不是说你不应该使用
信息
——这只是使用起来的巨大痛苦;)说真的,它是用来优化和更高级的用例的,所以如果没有更好的解决方案,你应该毫不犹豫地使用它。有一些库()可以用来更容易地解析对象

也就是说,我认为有几种方法可以解决这个问题:

1.)在查询解析器内

不幸的是,如果有许多不同的查询返回片段,那么最终将导致冗余

2.)片段类型上现有字段(或附加字段)的解析程序内部

如果您走这条路线,并且需要将参数传递到查询字段,则可以使用info提取这些参数。或者,您也可以在查询解析器中改变上下文对象,并将这些参数附加到它。然后,查询解析器“下面”的所有解析器(如片段字段的解析器)都可以通过上下文访问这些参数


3.)Apollo Server允许您在配置其中间件时定义
formatResponse
函数。这本质上提供了一个钩子,在响应返回到客户端之前,可以对响应执行任何操作。您可以解析该函数内的响应,并从该函数调用另一个后端。

您说“我想获取该数据并将其发送到另一个后端”--您是否试图通过调用另一个API来解析
字段,或者您只是想将部分查询结果发布到另一个后端?第二个后端。我想把我从查询片段中得到的东西发布到items后端。谢谢你的评论和详细信息。因为我没有修改
info
,所以我认为这是最好的解决方法。我按回车键太快了,我想这就是我一直在寻找的东西。它保留原始参数,直到其中一个解析器返回“undefined”。