all repos — slides @ dd23301e4567c63669a7d53d084ef399ac52f436

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