all repos — slides @ ed0e0f08b83cf278601cbd190e474107275fc2a7

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![GraphQL](https://graphql.org/img/brand/logos/logo-wordmark.svg)
 11
 12_Tim Izzo - BDWA - Cours React_
 13
 14---
 15
 16## Qu'est-ce que GraphQL ?
 17
 18- C'est un _language de requête_ (QL) pour requêter des données organisées _en graphe_.
 19- 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.
 20- C'est une alternative aux API REST avec une approche plus structurée et typée.
 21
 22---
 23
 24## Avantages de GraphQL
 25
 26- **Demande de données précises**: 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.
 27- **Introspection**: GraphQL fournit un système de type pour découvrir et explorer le schéma de l'API.
 28- **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.
 29
 30---
 31
 32## Fonctionnement
 33
 34On ne peut pas expliquer plus clairement que le site officiel
 35
 36=> https://graphql.org/
 37
 38---
 39
 40Utiliser GraphQL dans un projet nécessite plusieurs étapes:
 41
 421. Définir un schéma GraphQL
 432. Développer le backend
 443. Faire des requêtes depuis le frontend
 45
 46---
 47
 48## Schéma GraphQL
 49
 50- Le schéma GraphQL est un contrat entre le client et le serveur.
 51- Il définit les types de données disponibles et les opérations pouvant être effectuées sur ces types.
 52
 53```graphql
 54type User {
 55  id: ID!
 56  name: String!
 57  email: String!
 58}
 59
 60type Query {
 61  getUser(id: ID!): User
 62  getUsers: [User]!
 63}
 64
 65type Mutation {
 66  removeUser(id: ID!): Boolean
 67}
 68```
 69
 70---
 71
 72## Queries & Mutations
 73
 74- Une **Query** permet de récupérer des données (read-only)
 75- Une **Mutation** permet d'effectuer un changement sur les données (création, modification, suppression,...)
 76- Une **Subscription** permet à un front de suivre des changements côté backend [pas abordé]
 77
 78---
 79
 80# Exploration d'un graphe existant
 81
 82=> https://rickandmortyapi.com/graphql
 83
 84---
 85
 86## Backend
 87
 88Le backend doit faire correspondre un **resolver** à chaque élément
 89de `Query` et `Mutation`.
 90
 91Par exemple:
 92
 93```typescript
 94const resolvers = {
 95  getUser: (id: string) => {
 96    const users = knex("users").select(["id", "name", "email"]).where({ id });
 97    return users?.[0];
 98  },
 99};
100```
101
102---
103
104Faire correspondre un schéma GraphQL à des resolvers demande un peu de code
105qui est toujours le même.
106
107En général, on préfère utiliser un framework tout prêt pour éviter
108de ré-inventer la roue quand on doit développer un backend GraphQL.
109
110Le framework le + utilisé est [Apollo](https://www.apollographql.com/).
111
112---
113
114## Apollo
115
116Apollo est un ensemble d'outils pour:
117
118- Créer un serveur GraphQL: **Apollo Server**
119- Créer un client GraphQL: **Apollo Client**
120- Gérer ses schémas à grande échelle: **GraphOS**
121
122---
123
124## Requête depuis un client
125
126On va utiliser pour cela [Apollo Client](https://www.apollographql.com/docs/react/)
127qui permet une utilisation directement dans React.
128
129---
130
131## Configuration du client
132
1331. Installation des modules
134
135   ```bash
136   npm install @apollo/client graphql
137   ```
1382. Création du client
139
140   ```typescript
141   import { ApolloClient, InMemoryCache } from "@apollo/client";
142
143   const client = new ApolloClient({
144     uri: "https://rickandmortyapi.com/graphql",
145     cache: new InMemoryCache(),
146   });
147   ```
1483. Mise à disposition du client pour React
149   ```typescript
150   <ApolloProvider client={client}>
151       <App />
152   </ApolloProvider>,
153   ```
154---
155
156## Utilisation
157
158```typescript
159import { gql } from '@apollo/client';
160
161const CHARACTERS_QUERY = gql`
162 query {
163  characters {
164    results {
165      id
166      name
167      status
168    }
169  }
170 }
171`
172
173const Compo = () => {
174    const { loading, error, data } = useQuery(CHARACTERS_QUERY);
175
176    return ...
177}
178
179```
180
181---
182
183## Avec des arguments
184
185```typescript
186import { gql } from '@apollo/client';
187
188const CHARACTER_QUERY = gql`
189 query getCharacter($id: ID!) {
190  character(id: $id) {
191    id
192    name
193    status
194  }
195 }
196`
197
198const Compo = () => {
199    const { loading, error, data } = useQuery(CHARACTER_QUERY, {
200        variables: {id: 5}
201    });
202
203    return ...
204}
205```
206
207---
208
209## Mutation
210
211```typescript
212const CREATE_POST_MUTATION = gql`
213  mutation createPost($post: PostInput!) {
214    createPost(data: $post) {
215      id
216      name
217    }
218  }
219`;
220
221const [createPost, { data, loading, error }] =
222  useMutation(CREATE_POST_MUTATION);
223```
224
225> Cet exemple ne fonctionnera pas sur l'API GraphQL de Rick & Morty. C'est uniquement pour donner un exemple de mutation.
226
227---
228
229## Mise en place pour le TP
230
231Tim crée un serveur Strapi avec un modèle "Post" permettant de stocker des articles ainsi que le plugin GraphQL.
232
233> Les permissions pour CRUD le nouveau modèle doivent être ouvertes.
234
235---
236
237## Travail pratique
238
239Créer un simple frontend **Typescript** avec ViteJS qui va lister les articles de blog
240disponibles et en créer un nouveau au clique sur un bouton (avec du
241contenu par défaut).
242
243---
244
245On peut faire encore + pratique en générant
246automatiquement des hooks prêt-à-l'emploi pour chaque
247requête que l'on souhaite faire.
248
249Par exemple:
250
251```typescript
252const { data, loading, error } = usePostsQuery();
253const { data, loading, error } = usePostQuery({ variables: { id: 5 } });
254```
255
256---
257
258## GraphQL codegen
259
260Avec [codegen](https://the-guild.dev/graphql/codegen), on peut écrire l'ensemble
261de nos queries et mutations dans des fichiers _.gql_ et lancer un petit
262script qui nous génère des hooks pratiques.
263
264---
265
266## Travail pratique
267
268Mettre en place [codegen](https://the-guild.dev/graphql/codegen) dans notre projet
269commun pour mieux organiser nos appels GraphQL.
270
271---
272
273## Hands-On - Authentification
274
275Dans le monde réel, il faut s'authentifier auprès d'une API pour pouvoir l'utiliser.
276
277Nous allons regarder comment configurer Apollo Client ensemble pour se connecter auprès de Strapi puis lui dire d'utilise le token JWT récupéré lorsqu'il fait une requête.