all repos — slides @ 775cf26eb13ba22fffee66102b4d8a9032558b94

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   ```
138
1392. Création du client
140
141   ```typescript
142   import { ApolloClient, InMemoryCache } from "@apollo/client";
143
144   const client = new ApolloClient({
145     uri: "https://rickandmortyapi.com/graphql",
146     cache: new InMemoryCache(),
147   });
148   ```
149
1503. Mise à disposition du client pour React
151   ```typescript
152   <ApolloProvider client={client}>
153       <App />
154   </ApolloProvider>,
155   ```
156
157---
158
159## Utilisation
160
161```typescript
162import { gql } from '@apollo/client';
163
164const CHARACTERS_QUERY = gql`
165 query {
166  characters {
167    results {
168      id
169      name
170      status
171    }
172  }
173 }
174`
175
176const Compo = () => {
177    const { loading, error, data } = useQuery(CHARACTERS_QUERY);
178
179    return ...
180}
181
182```
183
184---
185
186## Avec des arguments
187
188```typescript
189import { gql } from '@apollo/client';
190
191const CHARACTER_QUERY = gql`
192 query getCharacter($id: ID!) {
193  character(id: $id) {
194    id
195    name
196    status
197  }
198 }
199`
200
201const Compo = () => {
202    const { loading, error, data } = useQuery(CHARACTER_QUERY, {
203        variables: {id: 5}
204    });
205
206    return ...
207}
208```
209
210---
211
212## Mutation
213
214```typescript
215const CREATE_POST_MUTATION = gql`
216  mutation createPost($post: PostInput!) {
217    createPost(data: $post) {
218      id
219      name
220    }
221  }
222`;
223
224const [createPost, { data, loading, error }] =
225  useMutation(CREATE_POST_MUTATION);
226```
227
228> Cet exemple ne fonctionnera pas sur l'API GraphQL de Rick & Morty. C'est uniquement pour donner un exemple de mutation.
229
230---
231
232## Mise en place pour le TP
233
234Tim crée un serveur Strapi avec un modèle "Post" permettant de stocker des articles ainsi que le plugin GraphQL.
235
236> Les permissions pour CRUD le nouveau modèle doivent être ouvertes.
237
238---
239
240## Travail pratique
241
242Créer un simple frontend **Typescript** avec ViteJS qui va lister les articles de blog
243disponibles et en créer un nouveau au clique sur un bouton (avec du
244contenu par défaut).
245
246---
247
248On peut faire encore + pratique en générant
249automatiquement des hooks prêt-à-l'emploi pour chaque
250requête que l'on souhaite faire.
251
252Par exemple:
253
254```typescript
255const { data, loading, error } = usePostsQuery();
256const { data, loading, error } = usePostQuery({ variables: { id: 5 } });
257```
258
259---
260
261## GraphQL codegen
262
263Avec [codegen](https://the-guild.dev/graphql/codegen), on peut écrire l'ensemble
264de notre queries et mutations dans des fichiers _.gql_ et lancer un petit
265script qui nous génère des hooks pratiques.
266
267---
268
269## Travail pratique
270
271Mettre en place [codegen](https://the-guild.dev/graphql/codegen) dans notre projet
272commun pour mieux organiser nos appels GraphQL.
273
274---
275
276## Hands-On - Authentification
277
278Dans le monde réel, il faut s'authentifier auprès d'une API pour pouvoir l'utiliser.
279
280Nous 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.