Apollo-link: [apollo-link-offline] Какая у вас идея?

Созданный на 5 окт. 2017  ·  38Комментарии  ·  Источник: apollographql/apollo-link

Привет, я был бы очень рад принять участие в создании этой функции. Потому что мне это очень нужно для настоящего проекта. Но для начала мне нужны подсказки. У кого-нибудь есть какие-либо идеи?

enhancement

Самый полезный комментарий

Привет, ребята, я попытался собрать воедино базовую реализацию для react-native, которая имеет поведение, подобное apollo-offline .
(пингует https://github.com/Malpaux/apollo-offline/issues/14)

Вы можете проверить это в этой сущности: https://gist.github.com/lachenmayer/2e364a5ca9ae0918eb032867d0c6720d

Это комбинация:

Когда устройство переходит в автономный режим, запросы будут поставлены в очередь и будут исключены из очереди, когда оно вернется в режим онлайн. ( apollo-link-queue )

Любой запрос, завершившийся ошибкой сети, будет повторяться (в настоящее время бесконечно). ( apollo-link-retry )
Обратите внимание, что это может быть связано либо с тем, что устройство отключено, либо серверная часть просто недоступна (например, если она не работает).

Однако, если мы сможем разрешить запрос из кеша, он не будет повторяться, и вместо этого данные в кеше будут использоваться в качестве ответа. Это реализовано в функции optimisticFetchLink .

На мой взгляд, такое поведение «оптимистичной выборки» является одной из наиболее важных частей apollo-offline, и любая будущая реализация apollo-link-offline должна поддерживать это. Это позволяет пользователю продолжать использовать приложение в обычном режиме в автономном режиме, пока данные были извлечены и сохранены в какой-то момент. На мой взгляд, это должно быть поведение по умолчанию для политики network-and-cache fetch , но, к сожалению, не похоже, что это изменится в ближайшее время (см. Https://github.com/apollographql/react-apollo/issues/ 604 # issuecomment-355648596).

Если вы сохраните суть как offlineLink.js , вы можете использовать ее следующим образом:

import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'

// get this from https://gist.github.com/lachenmayer/2e364a5ca9ae0918eb032867d0c6720d
import { createOfflineLink } from './offlineLink'

const cache = new InMemoryCache()
const networkLink = createHttpLink()

const offlineLink = createOfflineLink({ cache })

const link = ApolloLink.from([
  // ... + other links ...
  offlineLink,
  networkLink,
])

const client = new ApolloClient({
  cache,
  link,
}

Известные проблемы / недостающие биты

  • На данный момент это работает только с react-native. Проверка isOnline должна быть абстрагирована, чтобы сделать эту кроссплатформенную.
  • Если у вас есть только частичный ответ в кеше, вы получите отклоненное обещание где-то в конце строки, сообщающее вам, что ответ неполный. Я еще не рассмотрел, как это исправить, и как это решает apollo-offline. Если вы хотите попробовать исправить это, я был бы признателен за любые указатели по этому поводу.
  • В настоящее время вы не можете изменить какие-либо настройки повтора - это следует добавить в качестве дополнительного параметра конфигурации.
  • Вы не можете контролировать оптимистичную выборку. Вы должны иметь возможность устанавливать это независимо для каждого запроса. Я не большой поклонник реализации этого в apollo-offline (установка переменной запроса {__online_: true} ), но определенно должен быть какой-то способ сделать это.
  • Тестов явно тоже нет.

Я был бы признателен всем, кто ищет решение, попробовать это, и тогда мы сможем превратить его в полноценный модуль npm с типами, тестами, документами и всем остальным. На мой взгляд, такое поведение очень важно, и очень жаль, что у apollo-client 2 пока нет подходящего решения для этого.

Хороший ✌️

Все 38 Комментарий

Что вы считаете типичным вариантом использования?

Как офлайн-приложение:

  • Все запросы graphql добавляются в очередь. (можно хранить в кеше).
  • Когда приложение получает онлайн-сигнал, оно информирует ссылку о повторной отправке предыдущего запроса.

Я предполагаю, что он используется так:

import { NetInfo } from 'react-native';
import OfflineLink from 'apollo-link-offline';

const offlineLink = new OfflineLink({
  isOnlineAsync: () => NetInfo.isConnected.fetch(),
});

NetInfo.isConnected.addEventListener('change', (isConnected) => {
  if (isConnected) {
    offlineLink.resubmit();
  }
});

Я думаю, что это была бы потрясающая функциональность. На мой взгляд, это может произойти, если Apollo-link-offline определит набор запросов и мутаций, которые необходимо использовать в автономном режиме.

Как только они будут определены, в фоновом режиме приложения мы сможем получить все данные из запросов и сохранить их в локальном хранилище. Для Мутаций нам понадобятся все поля, созданные в локальном хранилище, чтобы мы могли хранить любые данные, созданные в автономном режиме.

Таким образом, мы по-прежнему можем выполнять функции в автономном режиме, сохраняя данные в локальном кеше.
Мы также прошли бы тесты Googles PWA, если бы могли ссылаться на Service Workers.
Затем, когда приложение возвращается в сеть, все мутации, произошедшие в локальном кеше, могут быть переданы обратно в API.

Очевидно, потребуется некоторая форма защиты параллелизма.

Меня беспокоит, что пользователь A (в автономном режиме) обновляет таблицу X, в то время как пользователь B (в сети) обновляет таблицу X, в то время как пользователь A был в автономном режиме. Здесь нам понадобится какая-то форма правил параллелизма. Я предполагаю, что это может быть привязано к дате, но это не решает проблему, если пользователь A переопределяет данные пользователя B без ведома пользователя B.

Или мы могли бы просто провалить Мутацию и позволить пользователю вручную обновлять, когда снова в сети.

Apollo Client 2 потрясающий, но эта функциональность была бы абсолютной собачьей чушью.

Я тоже буду большим поклонником этого. Я знаю, что были разные попытки решить эту проблему с помощью магазина Redux 1.0, но сделать его полноценным гражданином экосистемы Apollo 2.0 с последовательным подходом было бы довольно чудесно.

Большая часть того, что здесь было рассмотрено, уже имеет для меня большой смысл - в основном я хочу сохранить свои данные в локальном хранилище, а затем перенести их оттуда в Apollo после того, как это произошло. Во-вторых, выстраивание в очередь мутаций.

Как своего рода высшая цель, возможность втягивать еще больше данных в фоновом режиме также было бы здорово, и я буду стремиться к этому в любом случае. На самом деле я бы также хотел хранить почти все данные пользователя локально, просто чтобы сделать общие операции запросов намного быстрее, а затем повторно гидратироваться для полной точности, если позволяет сеть. Так что какое-то решение для этого угла нетерпеливой загрузки для последующего было бы отличным, особенно когда Service Workers начинают становиться жизнеспособными с Safari, наконец, имеющими их в техническом превью.

Я тоже в восторге от этого. @danieljvdm Получил репозитории apollo-client .

Я думаю, что RetryLink будет полезен для управления сетевыми ошибками и повторными попытками, хотя я бы хотел увидеть какой-то спад, как это было с redux-offline .

Это довольно круто. Проблема, на которую ссылается

Это все еще может быть достойным местом для начала и надстройки. В этой проблеме я указал на то, что в настоящее время у меня нет хорошего способа отслеживать изменения в кеше. Я действительно пытался реализовать первоначальное предложение @ 2WheelCoder ранее сегодня, но столкнулся с аналогичными проблемами. Проблема с созданием ApolloLink для «мониторинга изменений в хранилище» заключается в том, что он существует только в контексте между действием клиента и последующей записью в кэш. Таким образом, я могу перехватить запрос до того, как он уйдет (промежуточное ПО), и перехватить его до того, как он будет записан в кеш (послепрограммное обеспечение), но я не знаю, когда он был записан - я могу только догадываться (мой текущий взлом - это тайм-аут 1000 мс) ).

Еще один фатальный недостаток использования ссылки для сохранения в автономном режиме заключается в том, что она не учитывает подписки. Ссылка на подписку срабатывает только при открытии подписки, а не при последующих событиях (может быть, есть способ сделать это, который я пропустил?).

Это в основном то, где я сейчас нахожусь, и я довольно застрял - я думаю, что для дальнейшего развития мне, возможно, придется открыть PR для apollo-cache-inmemory.

@danieljvdm Я нахожусь в том же месте, и я думаю, что имеет смысл обрабатывать постоянство непосредственно в кеше после того, как вы столкнулись с той же проблемой, что и вы. HttpLink просто не подходит для этого, поскольку наблюдаемый завершается после запроса, но (обычно) до обновления кеша.

Хотя, возможно, стоит открыть PR для apollo-cache-inmemory, я также задаюсь вопросом, не было бы лучше включить его в новый проект. Модульность Apollo 2 вокруг кеша и ссылки, кажется, предполагает, что если вам нужен другой тип кеша, вы можете просто его построить. Может быть, следующим шагом будет проблема с apollo-client (я не думаю, что apollo-cache-inmemory имеет собственное репо)?

Приносим извинения за то, что по ссылкам здесь немного не по теме.

@holman Не могли бы вы дать ссылку на сервис-работника в превью сафари?

@sedubois упал (вроде как внезапно) месяц или два назад. Он находится в предварительном техническом обзоре , но впереди еще немало .

@ 2WheelCoder Мне нравится идея PR клиенту apollo для нового кеша. Возможно, apollo-offline-cache который может продлить apollo-cache-inmemory ? Я был бы готов помочь поработать над этим. Хотите открыть там вопрос?

@ 2WheelCoder @danieljvdm как насчет использования LocalForage для постоянства https://github.com/localForage/localForage Если вы, ребята, открываете PR, я был бы готов помочь

@danieljvdm Да, я открою вопрос, если ты хочешь получить пиар. В ближайшие полторы недели у меня не так много времени, но я рад присоединиться к ним после этого.

@Eishpirate Определенно согласен, что LocalForage великолепен. Я думаю, что способ, которым redux-persist удалось сохранить в магазине, был довольно надежным и, вероятно, может выступать в качестве достойного шаблона для следования в apollo-offline-cache .

Ребята, я использую пакет redux persist для сохранения данных хранилища в собственном AsyncStorage. Как мне это сделать сейчас? Любая идея?

@Eishpirate : работает ли localforage для нативной реакции? Глядя на диаграмму совместимости библиотеки, я не могу найти ничего о react native. https://github.com/localForage/localForage/wiki/Supported-Browsers-Platforms

Было бы очень грустно, если бы офлайн-функция apollo не работала для приложений ..

@timLoewel , это очень хороший

Это может вызвать непредвиденные проблемы в дальнейшем. Не уверен, что есть жизнеспособная альтернатива без необходимости изобретать велосипед.

Интересная статья, которая может иметь отношение к этому обсуждению https://blog.logrocket.com/building-an-offline-first-app-with-react-and-rxdb-e97a1fa64356?t=now

Очень многообещающе выглядит использование rxdb в качестве автономной базы данных. Это совместимо с React, React-Native, Vue, Angular, почти всеми наиболее популярными вариантами.

Проблема, которую я обнаружил, заключается в том, что она должна синхронизироваться с базой данных noSQL, такой как PouchDB (производная от CouchDB). В моем случае использования я использую реляционную базу данных SQL (Postgres), и все мои данные проверяются на уровне базы данных. Если бы мне пришлось использовать эту систему, мне нужно было бы поддерживать проверку через jsonschema.

Он не соответствует принципам DRY и определенно вызовет проблемы.

Другой вариант, который я нашел, - это Kinto http://docs.kinto-storage.org/en/stable/index.html, который работает с Postgres, поэтому следует избегать некоторых дополнительных уровней сложности, которые привнесет rxdb. Kinto использует HTTP, поэтому теоретически мы могли бы просто подключить его к Apollo-link-http https://github.com/apollographql/apollo-link/tree/master/packages/apollo-link-http.

Похоже, большая часть работы будет связана с кешированием.

Как насчет редукции? (Я серьезно)

Пакет apollo-link-offline , основанный на работе apollo-offline и ...
Пакет apollo-cache-redux . Используйте redux-offline / redux-persist так же, как сейчас это делает apollo-offline.

Apollo создал inmemory-cache как стандартное универсальное решение - я могу понять, почему они не хотели быть так тесно связаны с другой библиотекой. Но решение redux / redux-offline / redux-persis настолько проверенное в боевых условиях ... оно по-прежнему остается отличным выбором. Развитие идет очень активно по всем троим.

РЕДАКТИРОВАТЬ: apollo-cache-redux теперь существует, благодаря @rportugal

@giautm Я реализовал в значительной степени именно то, что вы описали для моего небольшого проекта недавно, и решил опубликовать его как действительно простой пакет: apollo-link-queue . Если у кого-то из вас есть идеи по улучшению, я хотел бы получить ваши предложения или комментарии.

Пожалуйста, каково состояние этого вопроса? Есть ли что-то, что мы можем использовать для офлайн-материалов, которые исходят от Apollo и не связаны с Redux Offline?

@smithaitufe ,
Да, вы можете использовать apollo-cache-persist .

@ Gregor1971
Спасибо за ссылку. Я попробую и представлю свои наблюдения.
На первый взгляд это выглядит круто и легко реализуется.

Чем это отличается от apollo-link-queue

Привет, ребята, я попытался собрать воедино базовую реализацию для react-native, которая имеет поведение, подобное apollo-offline .
(пингует https://github.com/Malpaux/apollo-offline/issues/14)

Вы можете проверить это в этой сущности: https://gist.github.com/lachenmayer/2e364a5ca9ae0918eb032867d0c6720d

Это комбинация:

Когда устройство переходит в автономный режим, запросы будут поставлены в очередь и будут исключены из очереди, когда оно вернется в режим онлайн. ( apollo-link-queue )

Любой запрос, завершившийся ошибкой сети, будет повторяться (в настоящее время бесконечно). ( apollo-link-retry )
Обратите внимание, что это может быть связано либо с тем, что устройство отключено, либо серверная часть просто недоступна (например, если она не работает).

Однако, если мы сможем разрешить запрос из кеша, он не будет повторяться, и вместо этого данные в кеше будут использоваться в качестве ответа. Это реализовано в функции optimisticFetchLink .

На мой взгляд, такое поведение «оптимистичной выборки» является одной из наиболее важных частей apollo-offline, и любая будущая реализация apollo-link-offline должна поддерживать это. Это позволяет пользователю продолжать использовать приложение в обычном режиме в автономном режиме, пока данные были извлечены и сохранены в какой-то момент. На мой взгляд, это должно быть поведение по умолчанию для политики network-and-cache fetch , но, к сожалению, не похоже, что это изменится в ближайшее время (см. Https://github.com/apollographql/react-apollo/issues/ 604 # issuecomment-355648596).

Если вы сохраните суть как offlineLink.js , вы можете использовать ее следующим образом:

import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'

// get this from https://gist.github.com/lachenmayer/2e364a5ca9ae0918eb032867d0c6720d
import { createOfflineLink } from './offlineLink'

const cache = new InMemoryCache()
const networkLink = createHttpLink()

const offlineLink = createOfflineLink({ cache })

const link = ApolloLink.from([
  // ... + other links ...
  offlineLink,
  networkLink,
])

const client = new ApolloClient({
  cache,
  link,
}

Известные проблемы / недостающие биты

  • На данный момент это работает только с react-native. Проверка isOnline должна быть абстрагирована, чтобы сделать эту кроссплатформенную.
  • Если у вас есть только частичный ответ в кеше, вы получите отклоненное обещание где-то в конце строки, сообщающее вам, что ответ неполный. Я еще не рассмотрел, как это исправить, и как это решает apollo-offline. Если вы хотите попробовать исправить это, я был бы признателен за любые указатели по этому поводу.
  • В настоящее время вы не можете изменить какие-либо настройки повтора - это следует добавить в качестве дополнительного параметра конфигурации.
  • Вы не можете контролировать оптимистичную выборку. Вы должны иметь возможность устанавливать это независимо для каждого запроса. Я не большой поклонник реализации этого в apollo-offline (установка переменной запроса {__online_: true} ), но определенно должен быть какой-то способ сделать это.
  • Тестов явно тоже нет.

Я был бы признателен всем, кто ищет решение, попробовать это, и тогда мы сможем превратить его в полноценный модуль npm с типами, тестами, документами и всем остальным. На мой взгляд, такое поведение очень важно, и очень жаль, что у apollo-client 2 пока нет подходящего решения для этого.

Хороший ✌️

@smithaitufe ,

Чем это отличается от apollo-link-queue?

Похоже, что apollo-link-queue делает умные вещи в зависимости от статуса соединения. apollo-cache-persist сохраняет кеш; позволяя, например, пользователям запускать и запускать ваше приложение в отключенном состоянии. Без сохранения кеша вашему приложению потребуется подключение для запуска,

Скорее всего, нам понадобятся оба, а еще @lachenmayer ,

@lachenmayer На первый взгляд ваш подход выглядит очень привлекательно.

Я полностью согласен с вами в необходимости чего-то вроде оптимистичной функции выборки apollo-offline . Это (или, скорее, его отсутствие) во многом вдохновило меня на создание apollo-offline .

Я сам не совсем удовлетворен тем, как мне пришлось реализовать выборочное включение / отключение функции оптимистической выборки в apollo-offline . Переменные запроса не были первым выбором, но они казались наиболее практичными. Что бы вы предложили?

Следующие пару недель будут для меня довольно напряженными. Однако после этого я был бы более чем счастлив внести свой вклад в реализацию современного автономного первого решения для Apollo - может быть, это будет новая версия пакета apollo-offline или что-то вроде apollo-link-offline .

Спасибо, @MLPXBrachmann!
Я считаю, что оптимистичная выборка должна контролироваться с помощью fetchPolicy - если я не хочу, чтобы что-либо получалось из кеша, я могу использовать network-only .

@lachenmayer @MLPXBrachmann

Я более чем готов и желаю внести свой вклад.

Я тоже ищу варианты реализации автономного поведения в приложении Apollo. Подход от @lachenmayer выглядит очень многообещающим, но поскольку он основан на apollo-link-retry, мутации, которые не были успешно применены, не будут сохранены, поэтому при обновлении страницы любые данные, которые не были переданы на сервер, будут отброшено (я предполагаю, что то же самое и с response-native, если приложение приостановлено). Есть ли работа или хотя бы обсуждение этого аспекта?

@nicocrm Понятно ... На данный момент обсуждение оффлайн-поддержки в основном apollo-link-offline . Надеюсь, это приведет к большему обсуждению и прогрессу, чем сейчас 😄

@benseitz Я однозначно за это. Эта функция вызывает большой интерес, поэтому я уверен, что есть место для проекта сообщества - пока я не дублирую или фрагментирую существующие усилия, я могу создать новую команду и репозиторий для apollo-link-offline и пригласить всех заинтересованных . У меня есть личный интерес, а также клиент, который действительно настаивает на этой функции, так что у меня есть несколько часов, чтобы потратить на нее. Я спрошу в репозитории apollo-offline, хотят ли они взять на себя инициативу, поскольку у них гораздо больше опыта.

У меня определенно есть личный интерес к этому - я буду рад поболтать с вами дальше на этом @nicocrm. Я пока не заметил каких-либо потерянных запросов на response-native, но, черт возьми, я действительно не тестировал все это должным образом (пока только с запросами, и, похоже, все работает нормально).

Я чувствую, что имеет смысл начать репо для этого. @MLPXBrachmann, который построил apollo-offline упомянутый выше, у него не будет времени потратить на улучшение apollo-offline в следующие пару недель, и я считаю, что имеет смысл назвать это apollo-link-offline .

Я не думаю, что есть какой-либо код, который можно будет повторно использовать из apollo-offline поскольку он очень специфичен для редукции.

@nicocrm Я полностью с вами согласен. Сохранение запросов / мутаций в очереди определенно должно быть тем, о чем потенциальный apollo-link-offline позаботится.

@benseitz Я тоже думаю, что было бы отличной идеей начать apollo-link-offline как усилие сообщества, и очень хотел бы участвовать в его разработке.

@lachenmayer Вы абсолютно правы, количество кода, разделяемого apollo-offline и запланированным пакетом apollo-link-offline , вероятно, будет почти нулевым. Однако я думаю, что многие из основных концепций первого все еще применимы при разработке автономного инструментария, установленного во вселенной Apollo 2.0.

В любом случае я был бы рад обсудить идеи для apollo-link-offline , дать отзыв о реализации и - как только мое расписание немного освободится - также внести свой код.

@MLPXBrachmann @lachenmayer @nicocrm Звучит как правильный способ сделать это!
Поскольку любой может открыть публичный канал на Apollo Slack . Я бы посоветовал открыть один под названием apollo-link-offline . Может быть, это немного упрощает общение между нами. Все важные решения должны быть задокументированы в GitHub Issues.

Вы согласны с тем, что я открываю и репо, и резервный канал, или кто-то из вас хочет это сделать?

Конечно, спасибо!

Я добавил вас троих в качестве соавторов репо . И вы можете присоединиться к каналу #apollo-link-offline в Apollo Slack

Конечно, всех приглашают к совместной работе над репозиторием GitHub и обсуждению на Slack :)
Я очень взволнован 💯

Для тех из вас, кто пришел сюда из поиска Google, я написал сводку всех существующих офлайн-технологий, доступных сегодня для Apollo Client 2.0.

https://github.com/benseitz/apollo-link-offline/issues/1#issuecomment -371678922

Работает ли Apollo над эквивалентом AWS AppSync? У нас уже есть сервер GraphQL, и нам необходимо автономное клиентское кеширование для запросов и изменений с использованием нашего сервера, а не решений AWS (например, Lamda, DynamoDB, Elastic Search).

надеюсь, что это сработает.

@masull Это было бы просто потрясающе. Я пробовал и не думал, что firebase или платформа parse работают для меня, поэтому наличие этой функции было бы великолепно.
Трудно настроить все с большим количеством пакетов ... совсем не весело :)

Была ли эта страница полезной?
0 / 5 - 0 рейтинги