Salut Ă  tous đź‘‹

React-Apollo est la bibliothèque incontournable pour utiliser GraphQL aux côtés de React. Leur documentation est vraiment complète, mais ils encouragent l'utilisation de (React) Hooks pour exécuter toutes vos requêtes.

Selon votre architecture front, il se peut que vous n'ayez pas envie de laisser tous vos composants React assumer ce type de responsabilité.

Dans mon cas, je devais intégrer GraphQL dans une application front React et m'adapter à l'architecture existante. L'application utilisait également les libs react-redux et redux-thunk. Le code est écrit de façon à ce que tout les appels d'API réseau sont exécutés via des actions redux (en utilisant redux-thunk).

En supposant que vous ayez une connaissance de redux-thunk et react-apollo, je vais vous montrer quelques exemples basiques d'actions.

Pour cet exemple, j'utiliserai une API GraphQL publique:

// client.jsimport ApolloClient from "apollo-client";import { InMemoryCache } from "apollo-cache-inmemory";import { HttpLink } from "apollo-link-http";import { setContext } from "apollo-link-context";import * as UserUtils from "../utils/user";const cache = new InMemoryCache();const link = new HttpLink({  uri: `https://directions-graphql.herokuapp.com/graphql`});const authLink = setContext((_, { headers }) => {  const token = UserUtils.getTokenFromLocalStorage();  return {    headers: {      ...headers,      authorization: token    }  };});const client = new ApolloClient({  cache,  link: authLink.concat(link)});export default client;
// actions.jsimport gql from 'graphql-tag';import graphQlClient from "client"export const signUp = (username = "johndoe", email = "john.doe@test.com", password = "mypassword") => (dispatch, getState) => {  dispatch(setLoading(true))  graphQlClient    .mutate({      mutation: gql`        mutation($username: String!, $email: String!, $password: String!) {          signUp(username: $username, email: $email, password: $password) {            user {              id,              username,              email            }          }        }      `,      variables: { username, email, password },      update: (_cache, result) => {        const { data: { signUp: { user: { username, email } } } } = result        dispatch(signIn(email, password))      },    })    .catch((error) => {      console.log('error', error)    })    .finally(() => {      dispatch(setLoading(false))    })}const setTokenToLocalStorage = (token) => {  localStorage.setItem('token', token)}const getTokenFromLocalStorage = () =>  localStorage.getItem("token") || null;export const signIn = (email, password) => (dispatch, getState) => {  dispatch(setLoading(true))  graphQlClient    .mutate({      mutation: gql`        mutation($email: String!, $password: String!) {          signIn(userIdentifier: $email, password: $password") {              token          }        }      `,      variables: { email, password },      update: (_cache, result) => {        const { data: { signIn: { token} }} = result        dispatch(setTokenToLocalStorage(token))      },    })    .catch((error) => {      console.log('error', error)    })    .finally(() => {      dispatch(setLoading(false))    })}export const direction = (coordinates = {startLat: 50.6333, startLng: 3.0667, endLat: 48.8534, endLng: 2.3488} , travelMode = "driving" ) => (dispatch, getState) => {  dispatch(setLoading(true))  graphQlClient.    graphQlClient.query({      query: gql`        input Coordinates {          startLat: Float!          startLng: Float!          endLat: Float!          endLng: Float        }        enum AllowTravelModes {          transit          driving          walking        }        query($coordinates: Coordinates, $travelMode: AllowTravelModes) {          direction(coordinates, travelMode: transit) {            steps {              stepInstruction            }          }        }      `,      variables: { coordinates , travelMode},    }).then((result) => {      const { data: { direction } } = result      dispatch(doSomethingWithDirection(direction))    })    .catch((error) => {      console.log('error', error)    })    .finally(() => {      dispatch(setLoading(false))    })}

Pour les besoins de l'exemple, j'ai utilisé des valeurs par défaut pour les paramètres d'actions. Comme vous pouvez le voir, vous manipulez facilement le client apollo graphql dans les actions redux thunks.

Pour conclure, je vais vous partager quelques liens pour vous aider dans votre parcours d'apprentissage de GraphQL et react-apollo ainsi que le repository contenant le code source de ces exemples.

Documentation :

Lectures avancées :

Code source :