Commit 574db8b9 authored by Robert Hostlowsky's avatar Robert Hostlowsky

minor cosmetics, fix typos

parent 870e4160
# GraphQL im Client: Introduction
Sobald wir mit einen GraphQL Client unserem GraphQL Server Anfragen schicken, werden die Vorteile von GraphQL noch leichter sichtbar.
Sobald wir mit einen GraphQL-Client unserem GraphQL-Server Anfragen schicken, werden die Vorteile von GraphQL noch leichter sichtbar.
Wir werden sehen, wie
* leicht der GraphQL im Client hinzugefügt werden kann,
* die React UI Komponenten mit nur geringem Aufwand erweitert werden können,
* GraphQL zum deklarativem Ansatz von React passt, und
* GraphIql die schnelle Anknüpfung an Schema und Server unterstützt
* durch den Einsatz einer Bibliothek, die Aspekt wie Fetching, Error handling und Caching von der Business Logik isoliert bleiben
* leicht GraphQL im Client hinzugefügt werden kann,
* die React-UI-Komponenten mit nur geringem Aufwand erweitert werden können,
* GraphQL zum deklarativem Ansatz von React passt,
* GraphiQL die schnelle Anknüpfung an Schema und Server unterstützt,
* durch den Einsatz einer Bibliothek Aspekte wie Fetching, Error Handling und Caching von der Business-Logik isoliert bleiben und
* sogenannte Co-location hilft, Wartbarkeit zu erhöhen
In unserem Beispiel werden wir Spotify-Daten auf einem Mobilen Gerät in einer React-Native-App vom eigenen GraphQL Server laden.
In unserem Beispiel werden wir Spotify-Daten auf einem mobilen Gerät in einer React-Native-App vom eigenen GraphQL-Server laden.
<img alt="teaser,Endresultat:fertige App" width="100" src="https://blog.codecentric.de/files/2017/11/spotify-expo-artists-marilyn.png"/>
<img alt="teaser,Spotify-Daten in einer React-Native-App vom eigenen GraphQL-Server laden" width="100" src="https://blog.codecentric.de/files/2017/11/spotify-expo-artists-marilyn.png"/>
Für eine schnelle Umsetzung - in wenigen Minuten - können wir Expo, also React Native, benutzen. Eine Demoversion ist auf expo.io veröffentlicht:
Für eine schnelle Umsetzung - in wenigen Minuten - können wir Expo, also React Native, benutzen. Eine Demoversion ist auf expo.io veröffentlicht.
### Bibliothek/Integration
Wir werden die **Apollo 2 Client Bibliothek** verwenden, die leichter einzusetzen ist, als
Facebooks eigene Bibliothek **"Relay"**. Relay kann zwar noch leistungsfähiger mit *schlechten Netzverbindungen* umgehen,
Wir werden die **Apollo-2-Client-Bibliothek** verwenden, die leichter einzusetzen ist als
Facebooks eigene Bibliothek Relay. Relay kann zwar noch leistungsfähiger mit schlechten Netzverbindungen umgehen,
würde aber mehr Komplexität und eine höhere Lernkurve mitbringen, und auch das Schema müsste daraufhin erweitert und angepasst werden.
# GraphQL im client mit Apollo und React
# GraphQL im Client mit Apollo und React
## Apollo Grundlagen
## Apollo-Grundlagen
Mit Apollo werden die Daten, ähnlich wie bei `flux/redux`, in einem lokalen State oder Cache gehalten.
Die UI Komponenten werden dann per HOC(Higher-Order-Component)-Ansatz gekapselt und an diesen State gekoppelt und mit den vom Server geladenen Werten gefüllt.
Dadurch kann die Verbindung zum Server an zentraler Stelle zu konfiguriert werden.
Apollo Version 1 baute noch direkt auf `redux` auf, aber mit Version 2 wurde es unabhängig von einem `redux-store`, modelliert den Cache selbst,
Die UI-Komponenten werden dann per HOC-(Higher-Order-Component-) Ansatz gekapselt, an diesen State gekoppelt und mit den vom Server geladenen Werten gefüllt.
Dadurch kann die Verbindung zum Server an zentraler Stelle konfiguriert werden.
Apollo Version 1 baute noch direkt auf `redux` auf, aber mit Version 2 wurde es unabhängig von einem `redux-store`, modelliert den Cache selbst
und bringt eine verbesserte Modularisierung mit sich.
Diese Komponenten stehen zur Verfügung:
XXX TODO: Add Grafik
* ApolloClient: Verbindung von Cache und Netzwerk Stack/Link
* ApolloInMemoryCache: Client seitiger GraphQL Cache mit Normalisierung (ist default Implementierung)
* ApolloLink: Netzwerk-Verbindung und Schnittstelle zum GraphQL Server
* ApolloInMemoryCache: clientseitiger GraphQL-Cache mit Normalisierung (ist Default-Implementierung)
* ApolloLink: Netzwerk-Verbindung und Schnittstelle zum GraphQL-Server
* ApolloProvider: Verbindung zwischen ApolloClient und den Komponenten in der Komponenten-Hierarchie
?? Durch diese neuen Komponenten, wird es möglich, zum Beispiel eine Offline-Unterstützung hinzuzufügen.
XXX TODO: Relevant? - Tatsächlich implementiert zum Beispiel Amazon AsyncApp eine eigene Implementierung des Caches auf Basis der redux-offline Bibliothek zur Offline Fähigkeit.
#### Installation der Bibliotheken und Benutzung in React
#### Installation der Bibliotheken und Benutzung in React
Nach Installation folgender Bibliotheken mit
......@@ -51,7 +46,7 @@ Nach Installation folgender Bibliotheken mit
npm install apollo-client-preset react-apollo graphql-tag graphql --save
```
können wir auf oberster Ebene den Kontext mit der Verbindung zum GraphQL Server definieren:
können wir auf oberster Ebene den Kontext mit der Verbindung zum GraphQL-Server definieren:
```javascript
// app.js
......@@ -77,7 +72,7 @@ ReactDOM.render(
document.getElementById('root')
);
```
Die Komponenten werden nun einfach per Apollo gekapselt und dadurch um die GraphQL Abfrage erweitert:
Die Komponenten werden nun einfach per Apollo gekapselt und dadurch um die GraphQL-Abfrage erweitert:
```javascript
// Hauptkomponente.js
......@@ -94,10 +89,10 @@ export default graphql(
)(ReactKomponente);
```
Dabei werden die Daten per React Mechanismen als "props" in die Komponente übergeben, dazu gleich mehr...
Dabei werden die Daten per React Mechanismen als "props" in die Komponente übergeben, dazu gleich mehr.
#### Abfrage Parametrisierung mit Variablen
Um Variablen in GraphQL Abfragen zu verwenden, kann das optionale `config` Object benutzt werden:
## Abfrage-Parametrisierung mit Variablen
Um Variablen in GraphQL-Abfragen zu verwenden, kann das optionale `config-Object benutzt werden:
```javascript
let config = {
......@@ -109,33 +104,35 @@ let config = {
};
```
In diesem Beispiel wird die Variable `byName` aus der den `props` der React Komponente mit dem Wert des `name` Felds gefüllt, also zum Beispiel mit `Marilyn`, wenn die gekapselte Komponente folgendermaßen verwendet wird:
In diesem Beispiel wird die Variable `byName` aus den props der React-Komponente mit dem Wert des `name`-Feldes gefüllt, also zum Beispiel mit `Marilyn`, wenn die gekapselte Komponente folgendermaßen verwendet wird:
```javascript
<GekapselteReactKomponente name='Marilyn' />
```
Durch diesen **deklarativen Ansatz** lässt sich GraphQL mit React Mechanismen ohne viel Aufwand in die UI integrieren.
Durch diesen **deklarativen Ansatz** lässt sich GraphQL mit React-Mechanismen ohne viel Aufwand in die UI integrieren.
# Mobiler Client: Spotify Music Info App
Schritte für die Umsetzung in unserem Spotify Beispiel:
Schritte für die Umsetzung in unserem Spotify-Beispiel:
* Tool installation: Expo, Android/iOS Simulator oder Expo-App auf Smartphone - siehe **extra Block: Expo**
* Tool-Installation: Expo, Android/iOS-Simulator oder Expo-App auf Smartphone (siehe Absatz “Expo...“)
* Projekt initialisieren mit Expo
* Einfache UI und Styling
* Modellierung der Datenabfrage mit graphiql
* Verbindung zum Server und Verknüpfung der Komponente mit GraphQL Abfrage
* Einfache UI und einfaches Styling
* Modellierung der Datenabfrage mit GraphiQL
* Verbindung zum Server und Verknüpfung der Komponente mit GraphQL-Abfrage
## Projekt initialisieren mit Expo
Wir installieren das Projekt mit Expo:
```bash
exp init spotify-graphql-client-react-native-expo --projectType blank
```
## Einfache UI und Styling
## Einfaches UI und Styling
Die generierte Seite muss noch abgeändert werden, indem der Rückgabewert der render Methode
Die generierte Seite muss noch abgeändert werden. Der Rückgabewert der `render`-Method
```javascript
// app.js
......@@ -162,25 +159,25 @@ const styles = StyleSheet.create({
});
```
mit
wird mit
```javascript
<View style={styles.container}>
<Query />
<Query />
<Artists name={this.state.artistName} />
</View>
```
ersetzt wird und folgende Zeilen hinzugefügt werden:
ersetzt und die folgenden Zeilen hinzugefügt:
#### Komponente: Liste der Künstler
```javascript
const Query = ({search = () => {} }) => <SearchBar
const Query = ({search}) => <SearchBar
onChangeText={search}
placeholder="artist name..." />;
const Artists = ({artists = []}) => <View>
const Artists = ({artists}) => <View>
{
artists.map(artist => (
<Text>
......@@ -229,7 +226,7 @@ export default class App extends React.Component {
}
```
## Verknüpfung der Komponente mit GraphQL Abfrage
## Verknüpfung der Komponente mit GraphQL-Abfrage
Für unser Beispiel benötigen wir die Liste der Künstler, mit Such-Parameter:
Dazu ergänzen wir in `main.js`:
......@@ -257,20 +254,14 @@ const ArtistsWithData = graphql(ArtistsQuery, config)(Artists);
und verwenden weiter oben `ArtistsWithData` anstatt `Artists`, also:
```<ArtistsWithData name={/**/} /> ```
## Fortsetzungen, weitere Optionen
Einige Fortgeschrittene Anwendungsfelder konnten nicht betrachtet werden, sind aber wesentlich und nutzen weitere Möglichkeiten von GraphQL:
* Verschachtelung der Komponenten und deren Abfragen,
* also zusätzlich Liste der Alben pro Künstler
* Änderungen per `mutation`: z.B. einen Künstler `liken`
* Optimistic UI: sofortige aktualisierung der Anzeige, ohne auf Rückgabe des Servers zu warten.
* Caching: Der Cache im Client kann sehr flexibel benutzt werden, und z.B. schon bei Start mit alten Werten aus dem Local Cache gefüllt werden, etc.
* Subscription: das interessanteste Feature ist die Möglichkeit, vom Server per websockets (oder auch MQTT, etc.) aktualisiert zu werden, wobei das gleiche Typ-System des Schemas benutzt wird.
Einige fortgeschrittene Anwendungsfelder konnten nicht betrachtet werden, sind aber wesentlich und nutzen weitere Möglichkeiten von GraphQL:
# Zusammenfassung
Durch die Typisierung erhält man bereits einen sehr guten **Tool-Support** in einer IDE, die durch Syntaxprüfung und Code Completion Arbeit sparen. Auch ein Linter, wie z.B. eslint kann die GraphQL-Abfragen im Source-Code parsen und Fehler finden, noch bevor manuell getestet werden muss. Was viel Zeit sparen und mühevolle Fehlersuche vermeiden hilft.
Durch den deklarativen Ansatz und durch die Möglichkeit, GraphQL und Komponenten im Source-Code zusammen zu speichern, fallen Anpassungen und Orientierung im Code leicht. Erweiterung um einfache Felder sind z.B. völlig unkompliziert.
Aus meiner Sicht ist auch der Austausch über die Schnittstelle zwischen "Front- und Backend- Teams" durch den **technischen Kontrakt** erleichtert. Der Kommunikations-Overhead wird verringert.
* Verschachtelung der Komponenten und deren Abfragen, also zusätzlich Liste der Alben pro Künstler
* Änderungen per GraphQL-`mutation`: z. B. einen Künstler 'liken'
* Optimistic UI: sofortige Aktualisierung der Anzeige, ohne auf Rückgabe des Servers zu warten
* Caching: Der Cache im Client kann sehr flexibel benutzt werden, und z. B. schon bei Start mit alten Werten aus dem Browser Cache gefüllt werden etc.
* GraphQL-Subscriptions: Das interessanteste Feature ist die Möglichkeit, vom Server per Websockets (oder auch MQTT etc.) aktualisiert zu werden, wobei das gleiche Typsystem des Schemas benutzt wird
* Es kann die Front- und Backend- Teams helfen, einen **technischen Kontrakt** festzulegen, und den Kommunikations-Overhead zu verringern.
* (siehe Teil 1: Automatische Schema Dokumentation und Playground)
Durch die Typisierung erhält man bereits einen sehr guten **Tool-Support** in einer IDE, die durch Syntaxprüfung und Code Completion Arbeit sparen. Auch ein Linter, wie z. B. eslint kann die GraphQL-Abfragen im Sourcecode parsen und Fehler finden, noch bevor manuell getestet werden muss – was viel Zeit spart und mühevolle Fehlersuche vermeidet.
Durch den deklarativen Ansatz und durch die Möglichkeit, GraphQL und Komponenten im Sourcecode zusammen zu speichern, fallen Anpassungen und Orientierung im Code leicht. Erweiterungen um einfache Felder sind z. B. völlig unkompliziert.
Aus meiner Sicht wird durch den **technischen Kontrakt** auch der Austausch über die Schnittstelle zwischen "Front- und Backend- Teams" erleichtert. Der Kommunikations-Overhead wird verringert.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment