all repos — slides @ fd8c9cfab9a3969c5b3d87d9724ed0d645b041d9

Reveal-md slides I made for various occasions

crea/react/GraphQL.md (view raw)

  1---
  2title: GraphQL
  3theme: ./_themes/5ika.css
  4highlightTheme: github
  5verticalSeparator: <!--v-->
  6revealOptions:
  7  transition: 'fade'
  8---
  9
 10
 11![GraphQL](https://graphql.org/img/brand/logos/logo-wordmark.svg)
 12
 13---
 14
 15**Nouveau format de slides !**
 16
 17- Moins de contenu sur les slides (prenez les notes qui vous semblent nécessaires)
 18- Slides en HTML
 19- Plus d'intéractivité, plus de pratique
 20
 21Ces slides sont disponibles sur https://5ika.ch/slides/GraphQL.md.
 22
 23---
 24
 25## Qu'est-ce que GraphQL ?
 26
 27- C'est un *language de requête* (QL) pour requêter des données organisées *en graphe*.
 28- Il permet de décrire de manière précise les données requises par une application cliente et d'obtenir ces données avec une seule requête.
 29- C'est une alternative aux API REST avec une approche plus structurée et typée.
 30
 31---
 32
 33## Avantages de GraphQL
 34
 35- **Demande de données précise**: Les clients peuvent demander exactement les données dont ils ont besoin, ce qui évite le sur-fetching ou le under-fetching de données.
 36- **Introspection**: GraphQL fournit un système de type pour découvrir et explorer le schéma de l'API.
 37- **Réduction des aller-retours**: Les clients peuvent obtenir toutes les données nécessaires en une seule requête, ce qui réduit les allers-retours entre le client et le serveur.
 38
 39---
 40
 41## Fonctionnement
 42
 43On ne peut pas expliquer plus clairement que le site officiel
 44
 45=> https://graphql.org/
 46
 47---
 48
 49Utiliser GraphQL dans un projet nécessite plusieurs étapes:
 50
 511. Définir un schéma GraphQL
 522. Développer le backend
 533. Faire des requêtes depuis le frontend
 54
 55---
 56
 57## Schéma GraphQL
 58
 59- Le schéma GraphQL est un contrat entre le client et le serveur.
 60- Il définit les types de données disponibles et les opérations pouvant être effectuées sur ces types.
 61
 62```graphql
 63type User {
 64  id: ID!
 65  name: String!
 66  email: String!
 67}
 68
 69type Query {
 70  getUser(id: ID!): User
 71  getUsers: [User]!
 72}
 73
 74type Mutation {
 75   removeUser(id: ID!): Boolean
 76}
 77```
 78
 79---
 80
 81## Queries & Mutations
 82
 83- Une **Query** permet de récupérer des données (read-only)
 84- Une **Mutation** permet d'effectuer un changement sur les données (création, modification, suppression,...)
 85- Une **Subscription** permet à un front de suivre des changements côté backend [pas abordé]
 86
 87---
 88
 89## Backend
 90
 91Le backend doit faire correspondre un **resolver** à chaque élément
 92de `Query` et `Mutation`.
 93
 94Par exemple:
 95
 96```typescript
 97const resolvers = {
 98    getUser: (id: string) => {
 99        const users = knex('users')
100                .select(['id', 'name','email'])
101                .where({id});
102        return users?.[0];
103    }
104}
105```
106
107---
108
109Faire correspondre un schéma GraphQL à des resolvers demande un peu de code
110qui est toujours le même.
111
112En général, on préfère utiliser un framework tout prêt pour éviter
113de ré-inventer la roue quand on doit développer un backend GraphQL.
114
115Le framework le + utilisé est [Apollo](https://www.apollographql.com/).
116
117---
118
119## Apollo
120
121Apollo est un ensemble d'outils pour:
122
123- Créer un serveur GraphQL: Apollo Server
124- Créer un client GraphQL: Apollo Client
125- Gérer ses schémas à grande échelle: GraphOS
126
127---
128
129## Travail pratique
130
131Ensemble, nous allons mettre en place un serveur GraphQL permettant de gérer un blog.
132
133Pour ce TP, nous allons développer ensemble sur les mêmes fichiers de manière
134synchronisée avec un [gitpod](https://www.gitpod.io/1).
135
136➡️ [Accéder au projet](https://gitpod.5ika.ch/?tkn=vvBXK79hp45yZofuTae2&folder=/home/vsc/projects/graphql-project)
137
138---
139
140**Première étape**: Définir le schémas.
141
142Nous devons définir:
143
144- Le type `Post` définissant un article de blog
145- Les *queries* et *mutations* possibles sur notre graphe. Ici, on veut CRUD des articles.
146
147---
148
149**Deuxième étape**: Installer Apollo Server
150
151=> https://www.apollographql.com/docs/apollo-server/getting-started
152
153---
154
155**Troisième étape**: Développer les resolvers.
156
157> Il est nécessaire de se répartir le travail pour éviter 
158> de se marcher sur les pieds.
159
160---
161
162**Quatrième étape**: Tester avec Apollo Sandbox
163
164Une interface graphique est automatiquement disponible sur le port
165utilisé par Apollo lorsqu'on est en mode dev.
166
167---
168
169## Requête depuis un client
170
171Une fois que le backend est prêt, on peut faire des requêtes
172depuis un client.
173
174On va utiliser pour cela [Apollo Client](https://www.apollographql.com/docs/react/)
175qui permet une utilisation directement dans React.
176
177
178---
179
180## Configuration du client
181
1821. Installation des modules
183    ```bash
184    npm install @apollo/client graphql
185    ```
186
1872. Création du client
188    ```typescript
189    import { ApolloClient, InMemoryCache } from '@apollo/client';
190
191    const client = new ApolloClient({
192    uri: 'http://localhost:4000',
193    cache: new InMemoryCache(),
194    });
195    ```
196
1973. Mise à disposition du client pour React
198    ```typescript
199    <ApolloProvider client={client}>
200        <App />
201    </ApolloProvider>,
202    ```
203
204---
205
206## Utilisation
207
208```typescript
209import { gql } from '@apollo/client';
210
211const POSTS_QUERY = gql`
212    query getPosts {
213      getPosts {
214        id
215        name
216      }
217    }
218`
219
220const Compo = () => {
221    const { loading, error, data } = useQuery(POSTS_QUERY);
222
223    return ...
224}
225
226```
227---
228
229## Avec des arguments
230
231```typescript
232import { gql } from '@apollo/client';
233
234const POST_QUERY = gql`
235    query getPost($postId: ID!) {
236      getPost(id: $postId) {
237        id
238        name
239      }
240    }
241`
242
243const Compo = () => {
244    const { loading, error, data } = useQuery(POST_QUERY, {
245        variables: {postId: 3}
246    });
247
248    return ...
249}
250```
251
252---
253
254## Mutation
255
256```typescript
257const CREATE_POST_MUTATION = gql`
258    mutation createPost($post: PostInput!) {
259        createPost(data: $post) {
260            id
261            name
262        }
263    }
264`;
265
266const [createPost, { data, loading, error }] = useMutation(CREATE_POST_MUTATION);
267```
268---
269
270## Travail pratique
271
272Créer un simple frontend avec ViteJS qui va lister les articles de blog
273disponibles et en créer un nouveau au clique sur un bouton (avec du 
274contenu par défaut).
275
276---
277
278On peut faire encore + pratique en générant
279automatiquement des hooks prêt-à-l'emploi pour chaque
280requête que l'on souhaite faire.
281
282Par exemple:
283
284```typescript
285const {data, loading, error} = usePostsQuery();
286const {data, loading, error} = usePostQuery({variables: {postId: 5}});
287```
288
289---
290
291## GraphQL codegen
292
293Avec [codegen](https://the-guild.dev/graphql/codegen), on peut écrire l'ensemble
294de notre queries et mutations dans des fichiers *.gql* et lancer un petit
295script qui nous génère des hooks pratiques.
296
297---
298
299## Travail pratique
300
301Mettre en place [codegen](https://the-guild.dev/graphql/codegen) dans notre projet
302commun pour mieux organiser nos appels GraphQL.
303
304---
305
306# Exploration d'un graphe existant
307
308=> https://rickandmortyapi.com/graphql