GraphQL查询结果中未返回扩展

时间:2019-09-10 07:45:34

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

我正在这样创建一个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
                }
            }
        }
    `})

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

知道为什么吗?

非常感谢您的帮助

2 个答案:

答案 0 :(得分:1)

we wrote up之前有一种小技巧:

您需要创建一个自定义的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客户端回购跟踪this feature request

上还有一个未解决的问题

答案 1 :(得分:0)

我对ApolloClient没有任何了解,但是我尝试在shopify graphql app中运行您的查询。它返回带有扩展名的结果。请在下面找到屏幕截图。另外,您可以在ApolloClient github中提出问题。

enter image description here