Apollo-Offline fornece uma interface de rede personalizada e um aprimorador de armazenamento Redux que permite o desenvolvimento contínuo de aplicativos off-line usando o cliente Apollo GraphQL.
Apollo-Offline é construído sobre Redux-Offline (e, portanto, herda todos os seus recursos).
O objetivo é fazer uso dos recursos off-line (-ish) existentes do Apollo (por exemplo, cache integrado e respostas otimistas para mutações). Isso significa que, ao migrar, seu código não precisará mudar muito (desde que você já esteja usando esses recursos).
Com o Apollo-Offline, o código de suas consultas e mutações parece exatamente como seria sem ele.
Há uma exceção a isso: o recurso de “busca otimista” .
O que a "busca otimista" faz é tentar primeiro ler a resposta de uma consulta do cache, mas se (e somente se!) uma conexão de rede estiver disponível, obterá a resposta do servidor em segundo plano e a gravará no cache (nesse ponto por exemplo, componentes React empacotados serão atualizados uma segunda vez).
Basicamente, isso significa que as consultas da sua UI sempre funcionarão se os dados solicitados estiverem disponíveis no cache local e sempre manterão os dados armazenados em cache consistentes com os dados do servidor, se puderem ser acessados.
Nota: Na minha opinião, é isso que fetchPolicy: 'cache-and-network'
deveria fazer (mas não faz - ocorre um erro se o servidor não puder ser alcançado).
Para habilitá-lo, adicione um campo __offline__
com um valor verdadeiro às variáveis de consulta dessa consulta específica (ou seja, variables: { __offline__: true }
).
Para obter mais instruções, consulte os exemplos abaixo.
usando fio
yarn add apollo-offline
ou npm
npm install --save apollo-offline
O Apollo-Offline também exige que você tenha as seguintes dependências de pares instaladas:
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 ) ,
) ,
) ;
Nota: Uma vez configurado, o Apollo-offline intercepta todas as consultas/mutações para permitir seu comportamento off-line primeiro.
Se você quiser excluir seletivamente algumas consultas/mutações disso, você pode voltar ao comportamento padrão do Apollo adicionando um campo __online__
com um valor verdadeiro às variáveis de consulta dessa consulta/mutação específica (ou seja, 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 */ ,
} ) ;
No seu ponto de entrada:
/* 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' ) ,
) ;
Ao embrulhar seus componentes:
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 */ ) ;
Isto é o que você faz depois de clonar o repositório:
yarn / npm install
(Instalar dependências)
Executar TSLint
npm run lint
Tente corrigir erros de linting automaticamente
npm run lint:fix
Execute testes de unidade Jest usando
npm test
npm run test:coverage
Os testes são definidos no mesmo diretório em que o módulo reside. Eles são especificados nos arquivos '[module].test.js'.
Para construir o projeto, execute
npm run build
Isso salva o código pronto para produção em 'dist/'.