Commit 4d00e812 authored by Robert Hostlowsky's avatar Robert Hostlowsky

restructured blog and all current drafts

parent 53128726
Graph.cool service ...
\ No newline at end of file
# Introduction
In diesem Teil werden wir den Server aus Teil 1 nutzen, um Spotify Daten auf einem Mobilen Gerät in einer ReactNative App zu laden.
Als ich neulich an Board eines Flugzeuges einen Internetzugang über eine Sateliten-Verbingung nutzen konnte, war ich überrascht, wie sich "Internet anfühlt", wenn Antwortzeiten deutlich spürbar werden.
Selbst heutige Mobilfunkverbindung fühlen sich gewöhnlich schneller an...
Es ist aber nicht die Übertragung, denn sie ist schnell, sondern die Verzögerungen bis zum Verbindungsaufbau und bis zur eintreffenden Antwort.
~~Hier ist mir auch sofort eingefallen, dass ein n+1 REST Ansatz im Web-Client hier eine schlechte Wahl ist, aber dieses Problem auf einfache Art mit GraphQL gelöst, indem nur ein Austausch notwendig ist.~~
GraphQL im Client:
* einfach zu integrieren
* speed up durch Schema
In diesem Artikel soll gezeigt werden, wie einfach die **Client-seitige Entwicklung** mit GraphQL in der **Zwischenschicht** ist.
Es kann die Front- und Backend- Teams helfen, einen **technischen Kontrakt** festzulegen, und den Kommunikations - overhead zu verringern.
~~Man denke nur an eine große Anwendung mit vielen (Domain-) Typen und vielen Schnittstellen zu verschieden Teams!!!~~
(siehe Teil 1: Automatische Schema Dokumentation und Playground)
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 *schlechtem Netzverbindungen* umgehen, würde aber erhöhte Komplexität und eine höhere Lernkurve mitbringen, und soll deshalb in einem späteren Blog beleuchtet werden soll...
Als **Beispiel** soll uns eine App zur Abfrage der Spotify Musikdatenbank dienen:
Für eine schnelle Umsetzung - in wenigen Minuten - können wir Expo, also React Native.
- Architektur: vom Client aus gibt es nur noch eine Abhängigkeit zu einem Server Endpoint, die Schnittstelle ist durch ein Schema festgelegt, validierbar.
?? Trennung der Aspekt wie Fetching, Error handling und Caching ausserhalb der Business Logik Sogenannte Colocation ermöglicht, das Mapping und das Festlegen, was geladen werden soll
# GraphQL im client mit Apollo und React
## Apollo Grundlagen
Mit Apollo werden die Daten, ähnlich wie bei `redux`, in einem Cache oder State gehalten, und per
HOC (Higher-Order-Component) Ansatz die UI Komponenten an diesen State ge koppelt werden.
Das ermöglicht es, die Verbindung zum Server an zentraler Stelle zu deklarieren.
Apollo 1 basierte und verwendete noch direkt `redux`, aber seit Apollo 2 wurde es unabhängig von einem `redux-store`
und eine bessere Modularisierung macht die es insgesamt schlanker.
Diese Komponenten stehen zu Verfügung:
* ApolloClient: Verbindung von Cache und Netzwerk Stack/Link
* ApolloLink: Netzwerk Verbindung und Schnittstelle zum GraphQL Server
* InMemoryCache: Client seitiger GraphQL Cache
* ApolloProvider XXX
Durch die neuen Komponenten, wird es möglich, zum Beispiel eine Offline-Unterstützung hinzuzufügen
SIEHE XXX,
...oder auch den Cache bei Neustart mit einem Zwischenstand zu füllen... XXX
#### Installation der Bibliotheken und Integration in React
```bash
npm install apollo-client-preset react-apollo graphql-tag graphql --save
```
Die Hauptkomponente wir typischerweise folgendermaßen per Apollo
mit dem GraphQL server verknüpft:
```javascript
import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
const client = new ApolloClient({
link: new HttpLink({
uri: 'http://localhost:3000' // GraphQL endpoint
}),
cache: new InMemoryCache()
// Alternativ, mit Cache füllen beim Neustart:
// new InMemoryCache().restore(window.__APOLLO_STATE__),
});
import { ApolloProvider } from 'react-apollo';
import { MainComponent } from './mainComponent';
// rendering in a react web app:
ReactDOM.render(
<ApolloProvider client={client}>
<MainComponent />
</ApolloProvider>,
document.getElementById('root')
);
```
#### Definition der GraphQL Operation per graphql-tag
Für jede UI Komponente, die per GraphQL gefüllt wird, sieht das Muster folgendermaßen aus:
```javascript
import gql from 'graphql-tag';
let UIComponentWithData = graphql(
gql`{ ... }`, // ES6 template string
config, // optional
)(UIComponent);
export { UIComponentWithData };
```
#### Definition GraphQL Query Variablen per Konfigurationsobjekt
Mit dem `config` Parameter kann mann die Query Variablen setzen, z.B.
wird hier aus den React Komponenten `props` das `name` Feld genutzt, um
eine Such Variable `byName` zu setzen:
```javascript
let config = {
options: (props) => ({
variables: {
byName: props.byName
}
})
};
```
Verwendet wird diese Konfiguration einfach auf die übliche Weise, so dass dieses
Feld über normale React Mechanismen aus einer Suchformularfeld gefüllt
werden kann, zum Beispiel so:
```javascript
<UIComponentWithData name='Marilyn' />
```
# Mobile Client / Anwendung
Die Schritte für die Umsetzung in unserem Spotify Beispiel:
* Tools installation: node.js, expo, iOS simulator oder client auf Smartphone
* Bei Expo.io Registrieren und Anmelden
* Projekt initialisieren
* Einfache UI und Styling anpassen
* Vorbereitung der Datenabfrage mit graphIql
* Verbindung zum Server und Verknüpfung mit Datenkomponente
## Tools installation: node.js, expo, iOS simulator oder client auf nativem Gerät
## Projekt initialisieren
```shell
npm install exp --global
exp register
exp login
exp init spotify-graphql-client-react-native-expo --projectType blank
cd spotify-graphql-client-react-native-expo
exp start
# in neuer shell:
exp ios # oder: exp android
```
![exp start](https://blog.codecentric.de/files/2017/11/spotify-expo-cli-exp-start.png)
Es erzeugt einen QR und eine URL, z.B.
```
[exp] Your URL is: exp://7m-2tf.lowsky.spot-cli.exp.direct:80
[exp] Logs for your project will appear below. Press Ctrl+C to exit.
in simulator, open expo, + button, add url and ...
```
Diese kann jetzt im iOS Simulator genutzt werden. Am einfachsten funktioniert es mit dem Expo Cli Tool per
```
# in neuer shell:
exp ios # oder unter Windows: exp android
```
![client im iOS Simulator](https://blog.codecentric.de/files/2017/11/spotify-expo-artists-marilyn.png)__Teaser :-)__
Auf dem Smartphone kann der QR Code in der Expo App eingescannt werden, so dass auch auf einem
nativen Gerät getestet werden kann.
## Vorbereitung: Datenabfrage mit graphiql
[online GraphIQL Abfrage](https://spotify-graphql-server.herokuapp.com/graphql?query=query%20artists(%24byName%3AString)%20%7B%0A%20%20queryArtists(byName%3A%24byName)%20%7B%0A%20%20%20%20name%0A%20%20%20%20id%0A%09%09image%0A%20%20%7D%0A%7D%0A&variables=%7B%22byName%22%3A%22Hot%20Chili%20Peppers%22%7D&operationName=artists)
XXX screenshot
## Anpassung der UI
Die generierte Seite muss noch abgeändert werden:
1. Wir verschieben `app.js` nach `main.js`
```javascript
// app.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Initial UI, more to come!</Text> // 1,alt
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
```
und ersetzend die Zeile `1,alt`:
```javascript
<Artists /> // 1, neu
```
XXX und fügen Zeile für den Import hinzu:
#### Komponente: Liste der Künstler
// MainComponent.js
```javascript
const Artists = ({artists = []}) => (
<View>
{
artists.map(artist => (
<Text>
{ artist.name }
</Text>
))
}
</View>
);
//Für unser Beispiel benötigen wir die Liste der Künstler, mit Such-Parameter:
const ArtistsQuery = gql`
query artists($byName: String!) {
artists: queryArtists(byName: $byName) {
image
name
}
}`;
const config = {
options: ({byName}) => ({
variables: {
byName: byName
}
})
};
const ArtistsWithData = graphql(ArtistsQuery, config)(Artists);
export default
<View>
<ArtistsWithData byName='Marilyn' />
</View>
```
Die `app.js` enthält die Apollo-HOC als oberste Komponente:
```javascript
import { ApolloClient, InMemoryCache } from 'apollo-client-preset';
import { HttpLink } from 'apollo-link-http';
import React from 'react';
import { ApolloProvider } from 'react-apollo';
import Main from './main';
const client = new ApolloClient({
link: new HttpLink({
uri: 'http://spotify-graphql-server.herokuapp.com/graphql'
}),
cache: new InMemoryCache()
});
export default class App extends React.Component {
render() {
return (
<ApolloProvider client={client}>
<Main />
</ApolloProvider>
);
}
}
```
## Fortsetzung
* Weitere Verschachtelung,
* Alben
* Mutation
# Zusammenfassung
? subscription
\ No newline at end of file
This diff is collapsed.
# Intro
GitHub ermöglicht seit 2016 auf seine umfangreiche [API per GraphQL zuzugreifen](https://githubengineering.com/the-github-graphql-api/).
Auch die [New York Times verwendet GraphQL](https://open.nytimes.com/react-relay-and-graphql-under-the-hood-of-the-times-website-redesign-22fb62ea9764). Wie man GraphQL selbst einsetzen kann, soll in dieser Blog-Reihe gezeigt werden.
In diesem Artikel wird ein GraphQL Server - [spotify-graphql-server on Github](https://github.com/lowsky/spotify-graphql-server) -
für den Zugriff auf Spotify entwickelt.
# gql?
2 years ago, gql?
a lot of news about gql,
* GitHub API, new york times...
Open source seit 2015
Neben referenzimplementierung von Facebook, viele Bibiliotheken für verschiedene Programmiersprachen entstanden. [awesome]
Warum sollten wir uns das genauer ansehen?
* netzwerk: overfetching, round-trips
* viele Client Versionen
* REST standard, aber ...
* wäre es nicht super, wenn beim Austausch automatisch
* * geprüft wird, ob die Daten vom Server im richtigen Fromat
* * das nicht per schema validierung (jsonschema), funktioniert client seitig, aber
* * server - seitig: alte clients
In diesem Artikel werden wir uns
kurz die Grundlagen und die idealen Use-Cases und Anwendungsfelder ansehen
anhand eines einfachen Beispiels für Spotify Musik Daten einem eigenen Server implementieren,
und Nutzung in einem Web client nutzen
eine existierende Platform
und sehen,
wie in bestehendes System integrieret werden kann
Grundlangen
In diesem Artikel haben wir bereits anhand eines Beispiels die Vorteile
von GraphQL gegenüber reinem REST Ansatz sehen können, und
wann sich der Einsatz lohnt.
* Exakte Definition, welche Daten benötigt und übermittelt werden sollen
(kein "over-fetching"): für mobile Datenverbindung
* Abfrage durch Aggregation auf Server-Seite mit nur einem Request:
für mobile Datenverbindung
* Zugriff auf zusammenhängende Daten möglich, so dass die API-Entwicklung
viel leichter von den
Anforderungen von der Client-Seite aus getrieben werden kann
* "Vertrag" durch Typisierung im Schema, der immer erlaubt, jede Abfrage
gegen die aktuelle
Schema-Definition zu überprüfen: Keine Fehler durch falsche Abfrage,
weil JSON Antwort unterschiedliche Feldnamen enthält
(wie "Name" statt "name")
* Nur ein einziger Endpoint für Abfragen von verschiedenen Datenquellen
notwendig.
Es kann sich jetzt bereits lohnen, auf GraphQL umzusteigen, oder
zumindest in ein bestehendes System zu integrieren,
denn die Hürden sind niedrig, und
ohne viel Aufwand, kann dieser Schritt ausprobiert werden!
In weiteren **Blog-Artikeln** werden wir herausfinden, wie wir zum Beispiel
* die Leistung durch Caching auf der **Server**-Seite mit [dataLoader](https://github.com/facebook/dataloader)
verbessern können,
* das optimierte [Relay](https://facebook.github.io/relay/)
auf der **Client**-Seite verwenden können,
und dazu das Schema erweitern müssen,
* GraphQL mit einer anderen Programmiersprache verwenden,
* Standard-Express-Features für die **Authentifizierung** für
personalisierte Infos (wie Playlisten) nutzen können,
* einige Goodies aus dem [awesome GraphQL Öko-System](https://github.com/chentsulin/awesome-graphql)
nutzen können
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