Метод Apollo - update() получает вызов дважды, оба раза с оптимистичными/поддельными данными

Я полностью застрял в проблеме Apollo, для которой я открыл проблему GitHub и получил нулевой ответ.

Я вызываю мутацию Apollo, используя optimisticResponse. То, как оно должно работать, как я понимаю, заключается в том, что update() вызывается дважды: сначала с оптимистичными данными, а затем с фактическими данными, поступающими из сети.

Но по какой-то причине мой код не работает так. Я получаю два вызова update(), как с оптимистичными данными.

Здесь репо, демонстрирующее это поведение: https://github.com/ffxsam/apollo-update-bug

  1. пряжа && пряжа dev
  2. Открыть в браузере, открыть консоль
  3. Введите текст и нажмите Enter.
  4. Повторите выше
  5. Обратите внимание на ошибку в консоли о дублирующих ключах. Это происходит потому, что временный идентификатор "??" не заменяется реальным UUID (необязательно). Вы можете открыть Vue DevTools, если они доступны, и проверить данные, чтобы увидеть их неверными

Ответы

Ответ 1

Я делал рытье, и я думаю, что нашел источник проблемы. К сожалению, у меня нет решения.

Короче говоря, проблема может быть связана с сетевой связью, называемой OfflineLink которая используется aws-appsync.

объяснение

aws-appsync есть ApolloLink, называемый OfflineLink который вмешивается в функцию request.

Что происходит, это примерно так:

  1. вы вызываете $apollo.mutate(...)
  2. ApolloClient.QueryManager инициализирует мутацию, которая запускает ваше update в первый раз с оптимистичным ответом. Это происходит внутри хранилища данных ApolloClient, markMutationInit вызывает markMutationResult, который вызывает ваше обновление.
  3. Операция graphql выполняется и достигает сети OfflineLink в сетевой цепочке.
  4. OfflineLink создает нового наблюдателя и отправляет информацию о мутации как действие.
  5. Следующая строка OfflineLink вызывает next функцию наблюдателя с optimisticResponse как если бы это был результат выполнения!
  6. Это вызывает второе update с результатом, который на самом деле является optimisticResponse.
  7. OfflineLink называет наблюдатель complete который решает свое обещание.
  8. console.log('done!'...

Между тем, OfflineLink позволяет исходной мутации даже отправлять запрос, а новая мутация генерируется и отправляется с параметрами, которые вы ему предоставили.

Ответ 2

Так что для чего это стоит я исправил это в vue, настроив appsync следующим образом:

const config = {
  url: awsExports.aws_appsync_graphqlEndpoint,
  region: awsExports.aws_appsync_region,

  auth: {
    type: awsExports.aws_appsync_authenticationType,
    apiKey: awsExports.aws_appsync_apiKey,
    jwtToken: async () => (await Auth.currentSession()).getIdToken().getJwtToken(),
  },
  disableOffline:true
}

обратите внимание на disableOffline:true