【问题标题】:Extensions not returned in GraphQL query resultsGraphQL 查询结果中未返回的扩展
【发布时间】:2020-01-11 22:34:59
【问题描述】:

我正在创建一个这样的 Apollo 客户端:

var { ApolloClient }    = require("apollo-boost");
var { InMemoryCache }   = require('apollo-cache-inmemory');
var { createHttpLink }  = require('apollo-link-http');
var { setContext }      = require('apollo-link-context');

exports.createClient = (shop, accessToken) => {

  const httpLink = createHttpLink({
    uri: `https://${shop}/admin/api/2019-07/graphql.json`,
  });
  const authLink = setContext((_, { headers }) => {
    return {
      headers: {
        "X-Shopify-Access-Token": accessToken,
        "User-Agent": `shopify-app-node 1.0.0 | Shopify App CLI`,
      }
    }
  });  

  return new ApolloClient({
    cache: new InMemoryCache(),
    link: authLink.concat(httpLink),
  });
};

点击 Shopify GraphQL API,然后运行这样的查询:

    return client.query({
        query: gql` {
            productVariants(first: 250) {
                edges {
                    node {
                        price
                        product {
                            id
                        }
                    }
                    cursor
                }
                pageInfo {
                    hasNextPage
                }
            }
        }
    `})

但是返回的对象只包含数据而没有扩展,这对于计算查询的实际成本是个问题。

知道为什么吗?

非常感谢您的帮助

【问题讨论】:

    标签: node.js graphql shopify apollo apollo-boost


    【解决方案1】:

    we wrote up 之前有一个 hacky 方法:

    您需要创建一个自定义的 apollo 链接(Apollo 相当于中间件)来拦截从服务器返回的响应数据,但在它被插入缓存和重新渲染组件之前。

    以下是我们从 API 的扩展中提取指标数据的示例:

    import { ApolloClient, InMemoryCache, HttpLink, ApolloLink } from 'apollo-boost'
    
    const link = new HttpLink({
      uri: 'https://serve.onegraph.com/dynamic?show_metrics=true&app_id=<app_id>',
    })
    
    const metricsWatchers = {}
    
    let id = 0
    
    export function addMetricsWatcher(f) {
      const watcherId = (id++).toString(36)
      metricsWatchers[watcherId] = f
      return () => {
        delete metricsWatchers[watcherId]
      }
    }
    
    function runWatchers(requestMetrics) {
      for (const watcherId of Object.keys(metricsWatchers)) {
        try {
          metricsWatchers[watcherId](requestMetrics)
        } catch (e) {
          console.error('error running metrics watcher', e)
        }
      }
    }
    
    // We intercept the response, extract our extensions, mutatively store them,
    // then forward the response to the next link
    const trackMetrics = new ApolloLink((operation, forward) => {
      return forward(operation).map(response => {
        runWatchers(
          response
            ? response.extensions
              ? response.extensions.metrics
              : null
            : null
        )
        return response
      })
    })
    
    function create(initialState) {
      return new ApolloClient({
        link: trackMetrics.concat(link),
        cache: new InMemoryCache().restore(initialState || {}),
      })
    }
    
    const apolloClient = create(initialState);
    

    然后在我们的 React 组件中使用结果:

    import { addMetricsWatcher } from '../integration/apolloClient'
    
    const Page = () => {
      const [requestMetrics, updateRequestMetrics] = useState(null)
    
      useEffect(() => {
        return addMetricsWatcher(requestMetrics =>
          updateRequestMetrics(requestMetrics)
        )
      })
    
    // Metrics from extensions are available now
    return null;
    }
    
    

    然后使用一些可变状态来跟踪每个请求及其结果,并使用该状态来呈现应用内的指标。

    根据您希望如何使用扩展程序数据,这可能适合您,也可能不适合您。该实现是非确定性的,并且在呈现的数据和您从扩展中提取的数据之间可能存在一些轻微的竞争条件。

    在我们的例子中,我们将性能指标数据存储在扩展中 - 非常有用,但也很辅助 - 所以我们认为这种权衡是可以接受的。

    还有一个关于 Apollo 客户端 repo 跟踪 this feature request 的未解决问题

    【讨论】:

    • 谢谢@sgrove。我不完全在那里,但你让我走上了正确的轨道。在你的 trackMetrics 方法中添加日志我可以看到很棒的扩展,但我不知道如何在我的 client.query 调用中添加它们?
    【解决方案2】:

    我不知道 ApolloClient,但我尝试在 shopify graphql app 中运行您的查询。它返回带有扩展名的结果。请在下面找到屏幕截图。也可以在ApolloClientgithub提问。

    【讨论】:

    • 谢谢。是的,我也在应用程序中这样做了。你说得对,我会联系 ApolloClient
    • 是的 RaphArbuz,如果您找到任何解决方案,请在评论中提及。谢谢
    猜你喜欢
    • 2018-10-08
    • 2020-10-23
    • 2019-07-07
    • 1970-01-01
    • 2020-11-02
    • 2019-01-16
    • 2016-11-18
    • 2018-08-16
    • 1970-01-01
    相关资源
    最近更新 更多