即使禁用了脱机,AWS AppSync查询也会返回缓存的响应 [英] AWS AppSync query returns cached response even when offline is disabled

查看:55
本文介绍了即使禁用了脱机,AWS AppSync查询也会返回缓存的响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用AWS AppSync的相当简单的节点应用程序.我能够成功运行查询和变异,但是最近发现,即使我运行两次查询,我也会得到相同的响应-即使我知道后端数据已更改.在这种特殊情况下,查询由lambda支持,在深入研究中,我发现查询似乎并没有在网络上发送出去,因为lambda不会在每次查询运行时触发-只是第一次.如果我使用控制台模拟查询,则一切运行正常.如果我重新启动应用程序,则在第一次运行查询时它可以正常运行,但是连续的查询再次每次都返回相同的值.

I have a fairly simple node app using AWS AppSync. I am able to run queries and mutations successfully but I've recently found that if I run a query twice I get the same response - even when I know that the back-end data has changed. In this particular case the query is backed by a lambda and in digging into it I've discovered that the query doesn't seem to be sent out on the network because the lambda is not triggered each time the query runs - just the first time. If I use the console to simulate my query then everything runs fine. If I restart my app then the first time a query runs it works fine but successive queries again just return the same value each time.

这是我的代码的一部分:

Here are some part of my code:

  client.query({
    query: gql`
    query GetAbc($cId: String!) {
      getAbc(cId: $cId) {
        id
        name
        cs
      }
    }`,
    options: {
      fetchPolicy: 'no-cache'
    },
    variables: {
      cid: event.cid
    }
  })
    .then((data) => {
      // same data every time
    })

编辑:尝试其他获取策略(例如 only-network )不会产生明显的差异.

Edit: trying other fetch policies like network-only makes no visible difference.

这是我设置客户端的方式,虽然不是超级干净,但似乎可以正常工作:

Here is how I set up the client, not super clean but it seems to work:

const makeAWSAppSyncClient = (credentials) => {
  return Promise.resolve(
    new AWSAppSyncClient({
      url: 'lalala',
      region: 'us-west-2',
      auth: {
        type: 'AWS_IAM',
        credentials: () => {
          return credentials
        }
      },
      disableOffline: true
    })
  )
}

getRemoteCredentials()
  .then((credentials) => {
    return makeAWSAppSyncClient(credentials)
  })
  .then((client) => {
    return client.hydrated()
  })
  .then((client) => {
    // client is good to use
  })

getRemoteCredentials 是一种将IoT身份验证转换为可与其他AWS开发工具包一起使用的常规IAM凭据的方法.这是可行的(因为如果没有的话,我将无法做到.)

getRemoteCredentials is a method to turn an IoT authentication into normal IAM credentials which can be used with other AWS SDKs. This is working (because I wouldn't get as far as I do if not).

我的问题似乎与此类似.

My issue seems very similar to this one GraphQL Query Runs Sucessfully One Time and Fails To Run Again using Apollo and AWS AppSync; I'm running in a node environment (rather than react) but it is essentially the same issue.

我认为这无关紧要,但是出于完整性考虑,我已经尝试过使用和不使用文档中的设置代码.这似乎没有什么区别(烦人的日志记录除外,请参见下文),但在这里是

I don't think this is relevant but for completeness I should mention I have tried both with and without the setup code from the docs. This appears to make no difference (except annoying logging, see below) but here it is:

global.WebSocket = require('ws')
global.window = global.window || {
  setTimeout: setTimeout,
  clearTimeout: clearTimeout,
  WebSocket: global.WebSocket,
  ArrayBuffer: global.ArrayBuffer,
  addEventListener: function () { },
  navigator: { onLine: true }
}

global.localStorage = {
  store: {},
  getItem: function (key) {
    return this.store[key]
  },
  setItem: function (key, value) {
    this.store[key] = value
  },
  removeItem: function (key) {
    delete this.store[key]
  }
};
require('es6-promise').polyfill()
require('isomorphic-fetch')

这取自:https://docs.aws.amazon.com/appsync/latest/devguide/building-a-client-app-javascript.html

在客户端设置中使用此代码且不使用 offlineDisabled:true 时,我看到此行在控制台上不断涌出:

With this code and without offlineDisabled: true in the client setup I see this line spewed continuously on the console:

redux-persist asyncLocalStorage需要一个全局localStorage对象.可以使用其他存储后端,也可以使用通用的Redux您可能应该有条件地像这样保留应用程序: https://gist.github.com/rt2zz/ac9eb396793f95ff3c3b

但是,此问题没有明显的区别.

This makes no apparent difference to this issue however.

更新:我对package.json的依赖关系,我在测试过程中已对其进行升级,因此我的yarn.lock包含的更新版本比此处列出的要多.不过: https://gist.github.com/macbutch/a319a2a7059adc3f68b9f9627598a8ca

Update: my dependencies from package.json, I have upgraded these during testing so my yarn.lock contains more recent revisions than listed here. Nevertheless: https://gist.github.com/macbutch/a319a2a7059adc3f68b9f9627598a8ca

更新#2 :我还从CloudWatch日志中确认,查询仅在一次上运行;我有一个在计时器上定期运行的变体,该变体已成功调用并在CloudWatch中可见.符合我的预期,但查询却没有.

Update #2: I have also confirmed from CloudWatch logs that the query is only being run once; I have a mutation running regularly on a timer that is successfully invoked and visible in CloudWatch. That is working as I'd expect but the query is not.

更新#3 :我已经调试到AppSync/Apollo代码,并且可以在 apollo-client/中将此代码的fetchPolicy更改为"cache-first"core/QueryManager.js (我的评论):

Update #3: I have debugged in to the AppSync/Apollo code and can see that my fetchPolicy is being changed to 'cache-first' in this code in apollo-client/core/QueryManager.js (comments mine):

QueryManager.prototype.fetchQuery = function (queryId, options, fetchType, fetchMoreForQueryId) {
    var _this = this;
    // Next line changes options.fetchPolicy to 'cache-first'
    var _a = options.variables, variables = _a === void 0 ? {} : _a, _b = options.metadata, metadata = _b === void 0 ? null : _b, _c = options.fetchPolicy, fetchPolicy = _c === void 0 ? 'cache-first' : _c;
    var cache = this.dataStore.getCache();
    var query = cache.transformDocument(options.query);
    var storeResult;
    var needToFetch = fetchPolicy === 'network-only' || fetchPolicy === 'no-cache';
    // needToFetch is false (because fetchPolicy is 'cache-first')
    if (fetchType !== FetchType.refetch &&
        fetchPolicy !== 'network-only' &&
        fetchPolicy !== 'no-cache') {
        // so we come through this branch
        var _d = this.dataStore.getCache().diff({
            query: query,
            variables: variables,
            returnPartialData: true,
            optimistic: false,
        }), complete = _d.complete, result = _d.result;
        // here complete is true, result is from the cache
        needToFetch = !complete || fetchPolicy === 'cache-and-network';
        // needToFetch is still false
        storeResult = result;
    }
    // skipping some stuff
    ...
    if (shouldFetch) { // shouldFetch is still false so this doesn't execute
        var networkResult = this.fetchRequest({
            requestId: requestId,
            queryId: queryId,
            document: query,
            options: options,
            fetchMoreForQueryId: fetchMoreForQueryId,
    }
    // resolve with data from cache
    return Promise.resolve({ data: storeResult });

如果我使用调试器将 shouldFetch 的值更改为true,那么至少我看到一个网络请求传出并执行了lambda.我想我需要解压正在更改fetchPolicy的那一行在做什么.

If I use my debugger to change the value of shouldFetch to true then at least I see a network request go out and my lambda executes. I guess I need to unpack what that line that is changing my fetchPolicy is doing.

推荐答案

确定,我发现了问题.这是我的问题的代码缩写:

OK I found the issue. Here's an abbreviated version of the code from my question:

 client.query({
    query: gql`...`,
    options: {
      fetchPolicy: 'no-cache'
    },
    variables: { ... }
  })

在这里看看哪里出了问题要容易一些.这应该是这样:

It's a little bit easier to see what is wrong here. This is what it should be:

 client.query({
    query: gql`...`,
    fetchPolicy: 'network-only'
    variables: { ... }
  })

原著中的两个问题:

  1. fetchPolicy:'no-cache'在这里似乎不起作用(我得到一个空响应)
  2. 不需要将 fetchPolicy 放入 options 对象中
  1. fetchPolicy: 'no-cache' does not seem to work here (I get an empty response)
  2. putting the fetchPolicy in an options object is unnecessary

graphql客户端指定选项的方式有所不同,我们在两者之间进行了切换.

The graphql client specifies options differently and we were switching between the two.

这篇关于即使禁用了脱机,AWS AppSync查询也会返回缓存的响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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