Apollo-Offline bietet eine benutzerdefinierte Netzwerkschnittstelle und einen Redux-Store-Enhancer, der eine nahtlose Offline-First-App-Entwicklung mithilfe des Apollo GraphQL-Clients ermöglicht.
Apollo-Offline baut auf Redux-Offline auf (und erbt somit alle dessen Funktionen).
Ziel ist es, die vorhandenen Offline(-ish)-Funktionen von Apollo zu nutzen (z. B. integriertes Caching und optimistische Antworten auf Mutationen). Das bedeutet, dass Sie bei der Migration nicht viel an Ihrem Code ändern müssen (sofern Sie diese Funktionen bereits nutzen).
Mit Apollo-Offline sieht der Code Ihrer Abfragen und Mutationen genauso aus wie ohne.
Hiervon gibt es eine Ausnahme: Die Funktion „Optimistischer Abruf“ .
Was „optimistischer Abruf“ bewirkt, ist, dass zunächst versucht wird, die Antwort einer Abfrage aus dem Cache zu lesen. Wenn jedoch (und nur dann!) eine Netzwerkverbindung verfügbar ist, wird die Antwort des Servers im Hintergrund abgerufen und (an diesem Punkt) in den Cache geschrieben z. B. werden umschlossene React-Komponenten ein zweites Mal aktualisiert).
Im Grunde bedeutet dies, dass die Abfragen Ihrer Benutzeroberfläche immer funktionieren, wenn die angeforderten Daten im lokalen Cache verfügbar sind, und dass die zwischengespeicherten Daten immer mit Ihren Serverdaten konsistent bleiben, sofern diese erreichbar sind.
Hinweis: Meiner Meinung nach sollte fetchPolicy: 'cache-and-network'
Folgendes tun (tut es aber nicht – es kommt zu einem Fehler, wenn der Server nicht erreichbar ist).
Um es zu aktivieren, fügen Sie ein __offline__
Feld mit einem wahren Wert zu den Abfragevariablen dieser spezifischen Abfrage hinzu (z. B. variables: { __offline__: true }
).
Weitere Anweisungen finden Sie in den Beispielen unten.
mit Garn
yarn add apollo-offline
oder npm
npm install --save apollo-offline
Für Apollo-Offline müssen außerdem die folgenden Peer-Abhängigkeiten installiert sein:
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 ) ,
) ,
) ;
Hinweis: Nach der Einrichtung fängt apollo-offline alle Abfragen/Mutationen ab, um sein nahtloses Offline-First-Verhalten zu ermöglichen.
Wenn Sie einige Abfragen/Mutationen selektiv davon ausschließen möchten, können Sie zum Standardverhalten von Apollo zurückkehren, indem Sie ein __online__
Feld mit einem wahrheitsgemäßen Wert zu den Abfragevariablen dieser spezifischen Abfrage/Mutation hinzufügen (z. B. 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 */ ,
} ) ;
In Ihrem Einstiegspunkt:
/* 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' ) ,
) ;
Beim Verpacken Ihrer Komponenten:
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 */ ) ;
Dies ist, was Sie tun, nachdem Sie das Repository geklont haben:
yarn / npm install
(Abhängigkeiten installieren)
Führen Sie TSLint aus
npm run lint
Versuchen Sie, Flusenfehler automatisch zu beheben
npm run lint:fix
Führen Sie Jest-Komponententests mit aus
npm test
npm run test:coverage
Tests werden im selben Verzeichnis definiert, in dem sich das Modul befindet. Sie werden in den Dateien „[module].test.js“ angegeben.
Um das Projekt zu erstellen, führen Sie es aus
npm run build
Dadurch wird der produktionsbereite Code in „dist/“ gespeichert.