GraphQL est un langage très puissant simplifiant les échanges de données entre une application et un serveur distant. Je l’ai utilisé avec React Native pour récupérer les données à afficher sur une vue. Cependant GraphQL permet aussi d’envoyer des données vers un serveur, on parle alors de Mutations.

La problématique

La qualité de réseau et l’accès à internet ne sont pas toujours assurés sur un appareil mobile puisque l’utilisateur se déplace. Ainsi, il y a plus de chance que la synchronisation avec le serveur échoue. Cela peut poser des problème, en particulier si l’utilisateur essaie d’envoyer des données vers le serveur (mutation). Nous voulons donc mettre en place un système qui renvoie les mutations tant qu’elles n’ont pas été délivrées au serveur. Nous allons faire en sorte que ce système fonctionne que l’application soit ouverte ou en arrière-plan.

Configurer React Apollo

React Apollo est une librairie qui permet d’utiliser Apollo, un client GraphQL, dans React. Apollo offre toutes les fonctionnalités pour exploiter facilement GraphQL. Il possède plusieurs extensions qui améliorent l’expérience et permettent de résoudre différentes problématiques.

Pour commencer, nous allons configurer un client avec Apollo et y ajouter les fonctionnalités dont nous avons besoin.

Les librairies qui contiennent « link » dans leur nom sont des extensions de Apollo. Nous allons nous concentrer sur RetryLink qui permet de définir les conditions dans lesquelles il faut réessayer une requête suite à une erreur.

Nous définissons ainsi une fonction dans la propriété attemps. Celle-ci est exécutée après chaque erreur pour déterminer si il faut lancer une nouvelle tentative ou non. Nous voyons alors deux conditions ci-dessus : soit le nombre de tentative est inférieur à 6, soit le nom de l’opération fait partie d’une liste que nous définissons.

Executer les mutations

Maintenant que le client est bien configuré, nous l’utilisons dans notre application en enveloppant celle-ci dans ApolloProvider.

Ensuite, dans les vues, nous utilisons le composant Mutation qui permet de lancer une mise à jour vers le serveur. Voici un exemple :

Le nom de la mutation est précisé après le mot clé mutation que nous voyons ci-dessus. Nous avions ajouté ce nom lors de la configuration du client dans le paragraphe précédent. De ce fait, si il y a une erreur réseau et que la mutation n’est pas correctement envoyée, l’application relance la mutation. Cependant, cette solution ne fonctionne que quand l’application est ouverte. Si l’utilisateur bascule sur une autre application, la fonction qui relance la tentative n’est plus appelée.

Lancer les mutations en arrière-plan

Pour remédier à ce dernier problème, nous allons configurer notre application pour s’exécuter en arrière-plan. La librairie react-native-brackground-job permet de faire cela facilement.  Nous installons cette librairie et la lions au projet React Native en lançant les commandes ci-dessous:

Nous déclarons ensuite un ou plusieurs travaux (jobs) qui doivent être exécutés en arrière-plan.

La fonction que nous définissons dans l’attribut job sera exécutée en arrière-plan. Dans notre cas, nous plaçons juste une fonction vide qui est suffisante pour garder l’application en marche en arrière-plan.

Nous modifions alors index.js (index.android.js ou index.ios.js selon les cas) pour enregistrer les travaux comme suit:

Enfin, dans le composant App, nous lançons les travaux en arrière-plans quand le composant est monté (dans componentDidMount). Nous ajoutons alors le code suivant dans la définition de App:

Comme on peut le voir, nous appelons BackgroundJob.schedule qui initialise les travaux en arrière-plan et s’exécute toutes les minutes.

Conclusion

Maintenant, quand l’application passe en arrière-plan et que des mutations n’ont pas été correctement envoyées, elles sont relancées automatiquement. Notre application continue ainsi à fonctionner comme il faut et à envoyer les données peu importe les conditions d’accès au réseau. Nous assurons ainsi autant que possible que toutes les modifications initialisées dans l’application sont bien transmises au serveur.