--- title: GraphQL theme: ./_themes/5ika.css highlightTheme: github verticalSeparator: revealOptions: transition: 'fade' --- ![GraphQL](https://graphql.org/img/brand/logos/logo-wordmark.svg) --- **Nouveau format de slides !** - Moins de contenu sur les slides (prenez les notes qui vous semblent nécessaires) - Slides en HTML - Plus d'intéractivité, plus de pratique Ces slides sont disponibles sur https://5ika.ch/slides/GraphQL.md. --- ## Qu'est-ce que GraphQL ? - C'est un *language de requête* (QL) pour requêter des données organisées *en graphe*. - 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. - C'est une alternative aux API REST avec une approche plus structurée et typée. --- ## Avantages de GraphQL - **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. - **Introspection**: GraphQL fournit un système de type pour découvrir et explorer le schéma de l'API. - **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. --- ## Fonctionnement On ne peut pas expliquer plus clairement que le site officiel => https://graphql.org/ --- Utiliser GraphQL dans un projet nécessite plusieurs étapes: 1. Définir un schéma GraphQL 2. Développer le backend 3. Faire des requêtes depuis le frontend --- ## Schéma GraphQL - Le schéma GraphQL est un contrat entre le client et le serveur. - Il définit les types de données disponibles et les opérations pouvant être effectuées sur ces types. ```graphql type User { id: ID! name: String! email: String! } type Query { getUser(id: ID!): User getUsers: [User]! } type Mutation { removeUser(id: ID!): Boolean } ``` --- ## Queries & Mutations - Une **Query** permet de récupérer des données (read-only) - Une **Mutation** permet d'effectuer un changement sur les données (création, modification, suppression,...) - Une **Subscription** permet à un front de suivre des changements côté backend [pas abordé] --- ## Backend Le backend doit faire correspondre un **resolver** à chaque élément de `Query` et `Mutation`. Par exemple: ```typescript const resolvers = { getUser: (id: string) => { const users = knex('users') .select(['id', 'name','email']) .where({id}); return users?.[0]; } } ``` --- Faire correspondre un schéma GraphQL à des resolvers demande un peu de code qui est toujours le même. En général, on préfère utiliser un framework tout prêt pour éviter de ré-inventer la roue quand on doit développer un backend GraphQL. Le framework le + utilisé est [Apollo](https://www.apollographql.com/). --- ## Apollo Apollo est un ensemble d'outils pour: - Créer un serveur GraphQL: Apollo Server - Créer un client GraphQL: Apollo Client - Gérer ses schémas à grande échelle: GraphOS --- ## Travail pratique Ensemble, nous allons mettre en place un serveur GraphQL permettant de gérer un blog. Pour ce TP, nous allons développer ensemble sur les mêmes fichiers de manière synchronisée avec un [gitpod](https://www.gitpod.io/1). ➡️ [Accéder au projet](https://gitpod.5ika.ch/?tkn=vvBXK79hp45yZofuTae2&folder=/home/vsc/projects/graphql-project) --- **Première étape**: Définir le schémas. Nous devons définir: - Le type `Post` définissant un article de blog - Les *queries* et *mutations* possibles sur notre graphe. Ici, on veut CRUD des articles. --- **Deuxième étape**: Installer Apollo Server => https://www.apollographql.com/docs/apollo-server/getting-started --- **Troisième étape**: Développer les resolvers. > Il est nécessaire de se répartir le travail pour éviter > de se marcher sur les pieds. --- **Quatrième étape**: Tester avec Apollo Sandbox Une interface graphique est automatiquement disponible sur le port utilisé par Apollo lorsqu'on est en mode dev. --- ## Requête depuis un client Une fois que le backend est prêt, on peut faire des requêtes depuis un client. On va utiliser pour cela [Apollo Client](https://www.apollographql.com/docs/react/) qui permet une utilisation directement dans React. --- ## Configuration du client 1. Installation des modules ```bash npm install @apollo/client graphql ``` 2. Création du client ```typescript import { ApolloClient, InMemoryCache } from '@apollo/client'; const client = new ApolloClient({ uri: 'http://localhost:4000', cache: new InMemoryCache(), }); ``` 3. Mise à disposition du client pour React ```typescript , ``` --- ## Utilisation ```typescript import { gql } from '@apollo/client'; const POSTS_QUERY = gql` query getPosts { getPosts { id name } } ` const Compo = () => { const { loading, error, data } = useQuery(POSTS_QUERY); return ... } ``` --- ## Avec des arguments ```typescript import { gql } from '@apollo/client'; const POST_QUERY = gql` query getPost($postId: ID!) { getPost(id: $postId) { id name } } ` const Compo = () => { const { loading, error, data } = useQuery(POST_QUERY, { variables: {postId: 3} }); return ... } ``` --- ## Mutation ```typescript const CREATE_POST_MUTATION = gql` mutation createPost($post: PostInput!) { createPost(data: $post) { id name } } `; const [createPost, { data, loading, error }] = useMutation(CREATE_POST_MUTATION); ``` --- ## Travail pratique Créer un simple frontend avec ViteJS qui va lister les articles de blog disponibles et en créer un nouveau au clique sur un bouton (avec du contenu par défaut). --- On peut faire encore + pratique en générant automatiquement des hooks prêt-à-l'emploi pour chaque requête que l'on souhaite faire. Par exemple: ```typescript const {data, loading, error} = usePostsQuery(); const {data, loading, error} = usePostQuery({variables: {postId: 5}}); ``` --- ## GraphQL codegen Avec [codegen](https://the-guild.dev/graphql/codegen), on peut écrire l'ensemble de notre queries et mutations dans des fichiers *.gql* et lancer un petit script qui nous génère des hooks pratiques. --- ## Travail pratique Mettre en place [codegen](https://the-guild.dev/graphql/codegen) dans notre projet commun pour mieux organiser nos appels GraphQL. --- # Exploration d'un graphe existant => https://rickandmortyapi.com/graphql