Apollo-Offline предоставляет настраиваемый сетевой интерфейс и средство расширения хранилища Redux, которое обеспечивает беспрепятственную разработку приложений в автономном режиме с использованием клиента Apollo GraphQL.
Apollo-Offline построен на основе Redux-Offline (и, таким образом, наследует все его функции).
Он направлен на использование существующих офлайн-функций Apollo (например, встроенного кэширования и оптимистических ответов на мутации). Это означает, что при миграции ваш код не придется сильно менять (пока вы уже используете эти функции).
С Apollo-Offline код ваших запросов и мутаций выглядит точно так же, как и без него.
Есть одно исключение из этого правила: функция «оптимистической выборки» .
Что делает «оптимистическая выборка», так это то, что она пытается сначала прочитать ответ на запрос из кеша, но если (и только если!) доступно сетевое соединение, он получит ответ сервера в фоновом режиме и запишет его в кеш (в этот момент например, упакованные компоненты React обновятся во второй раз).
По сути, это означает, что запросы вашего пользовательского интерфейса всегда будут работать, если запрошенные данные доступны в локальном кеше, и он всегда будет поддерживать соответствие кэшированных данных с данными вашего сервера, если они могут быть доступны.
Примечание. По моему мнению, именно это и должен делать fetchPolicy: 'cache-and-network'
(но не делает - возникает ошибка, если сервер недоступен).
Чтобы включить его, добавьте поле __offline__
с правдивым значением к переменным запроса этого конкретного запроса (т. е. variables: { __offline__: true }
).
Дополнительные инструкции см. в примерах ниже.
используя пряжу
yarn add apollo-offline
или НПМ
npm install --save apollo-offline
Apollo-Offline дополнительно требует, чтобы у вас были установлены следующие одноранговые зависимости:
apollo-client
redux
import { ApolloClient , createNetworkInterface } from 'apollo-client' ;
import { applyMiddleware , combineReducers , compose , createStore } from 'redux' ;
import config from '@redux-offline/redux-offline/lib/defaults' ;
import offline from 'apollo-offline' ;
// 1. Wrap your network interface
const { enhancer , networkInterface } = offline (
createNetworkInterface ( {
uri : `http://localhost` ,
} ) ,
) ;
// 2. Create your Apollo client
const client = new ApolloClient ( {
/* Your Apollo configuration here... */
networkInterface ,
} ) ;
// 3. Pass the client to the offline network interface
// (Optional, but needed for the optimistic fetch feature)
networkInterface . setClient ( client ) ;
// 4. Create your redux store
export const store = createStore (
combineReducers ( {
apollo : client . reducer ( ) ,
} ) ,
undefined ,
compose (
applyMiddleware ( client . middleware ( ) ) ,
// Apply offline store enhancer
// (You can pass your own redux-offline config, but the default one is a good starting point)
enhancer ( config ) ,
) ,
) ;
Примечание. После настройки apollo-offline перехватывает все запросы/мутации, чтобы обеспечить плавное поведение в режиме оффлайн.
Если вы хотите выборочно исключить из этого некоторые запросы/мутации, вы можете вернуться к поведению Apollo по умолчанию, добавив поле __online__
с правдивым значением к переменным запроса этого конкретного запроса/мутации (т. е. variables: { __online__: true }
). .
/* Setup goes here... */
// Queries
client . query ( { query : /* Your query here */ } ) ;
// - Using optimistic fetch feature
client . query ( {
fetchPolicy : 'network-only' ,
query : /* Your query here */ ,
variables : {
__offline__ : true , // Enable optimistic fetch
} ,
} ) ;
// Mutations
client . mutate ( {
mutation : /* Your mutation here */ ,
optimisticResponse : /* Your optimistic response here */ ,
update : /* Your update resolver here */ ,
} ) ;
В вашей точке входа:
/* Setup goes here... */
import { ApolloProvider } from 'react-apollo' ;
import { connect } from 'react-redux' ;
import App from './App' ; // Your main application component
// Component to postpone render until after Redux state has been rehydrated
const Rehydrated = connect ( ( { rehydrated } ) => ( { rehydrated } ) )
( ( props ) => props . rehydrated ? props . children : props . loading ) ;
const Loading = ( ) => < div > Loading... </ div > ;
ReactDOM . render (
< ApolloProvider client = { client } store = { store } >
< Rehydrated loading = { < Loading /> } >
< App />
</ Rehydrated >
</ ApolloProvider > ,
document . getElementById ( 'root' ) ,
) ;
При упаковке компонентов:
import React from 'react' ;
import { graphql } from 'react-apollo' ;
// Queries
const wrappedComponent = graphql ( /* Your query here */ ) ( /* Your component here */ ) ;
// - Using optimistic fetch feature
const wrappedComponent = graphql (
/* Your query here */ ,
{
options : {
fetchPolicy : 'network-only' ,
variables : {
__offline__ : true , // Enable optimistic fetch
} ,
} ,
} ,
) ( /* Your component here */ ) ;
// Mutations (you will want to provide an optimistic response when executing them)
const wrappedComponent = graphql (
/* Your mutation here */ ,
{
options : {
update : /* Your update resolver here */ ,
} ,
} ,
) ( /* Your component here */ ) ;
Вот что вы делаете после клонирования репозитория:
yarn / npm install
(Установить зависимости)
Выполнить TSLint
npm run lint
Попробуйте автоматически исправить ошибки линтинга
npm run lint:fix
Выполните модульные тесты Jest, используя
npm test
npm run test:coverage
Тесты определяются в том же каталоге, в котором находится модуль. Они указаны в файлах «[module].test.js».
Чтобы построить проект, выполните
npm run build
При этом готовый к производству код сохраняется в 'dist/'.