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