Fermer

octobre 9, 2019

Débuter avec GraphQL et React Native –


En 2012, Nick Schrock, ingénieur pour Facebook, a commencé à travailler sur un petit prototype afin de faciliter son passage à une ancienne API de partenaire non prise en charge qui alimentait l'actuel flux d'actualités Facebook. À l'époque, cela s'appelait «SuperGraph». Aujourd'hui, SuperGraph a contribué à façonner le langage de requête open source GraphQL, qui était en grande partie le mot à la mode ces derniers temps.

Facebook décrit GraphQL comme un “langage de requête pour les API et une exécution pour les remplir. requêtes avec vos données existantes ". En termes simples, GraphQL est une alternative au REST qui gagne en popularité depuis sa publication. Tandis qu'avec REST, un développeur rassemblait généralement les données d'une série de requêtes de points de terminaison, GraphQL lui permet d'envoyer une requête unique au serveur décrivant l'exigence de données exacte.

Vous voulez apprendre à réagir dès le départ à React Native? Cet article est un extrait de notre bibliothèque Premium. Obtenez une collection complète de livres natifs de React couvrant les bases, les projets, les astuces, les outils, etc., avec SitePoint Premium. Inscrivez-vous maintenant pour seulement 9 dollars par mois .

Prérequis

Pour ce didacticiel, vous aurez besoin d'une connaissance de base de React Native et d'une certaine connaissance de l'Expo . environnement. Vous aurez également besoin du client Expo installé sur votre appareil mobile ou d'un simulateur compatible installé sur votre ordinateur. Vous trouverez des instructions sur la procédure à suivre ici .

Présentation du projet

Dans ce didacticiel, nous allons démontrer la puissance de GraphQL dans un environnement React Native en créant un simple grain de café. application de comparaison. Pour vous permettre de vous concentrer sur tout ce que GraphQL a à offrir, j'ai créé le modèle de base de l'application utilisant Expo.

 Une maquette de notre application de comparaison de café

Pour commencer, vous pouvez cloner. ce repo et accédez à la branche «[ getting-started ]», qui inclut toutes nos vues de base pour commencer à ajouter nos données GraphQL, ainsi que toutes nos dépendances initiales, qui à ce stade sont:

 {
    "expo": "^ 32.0.0",
    "réagir": "16.5.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
    "react-navigation": "^ 3.6.1"
}

Pour cloner cette branche, vous devez ouvrir un terminal et exécuter la commande suivante:

 git clone https://github.com/jamiemaison/graphql-coffee-comparison.git

Pour ensuite accéder à la branche qui démarre vous accédez au référentiel cloné avec cd graphql-coffee-compare et exécutez git checkout Getting-started .

La prochaine étape consiste à installer nos dépendances. Pour ce faire, assurez-vous d’être sur le nœud v11.10.1 et exécutez npm install dans le répertoire racine du projet. Cela ajoutera toutes les dépendances énumérées ci-dessus à votre dossier node_modules .

Pour commencer à ajouter GraphQL à notre application React Native, nous allons devoir installer quelques dépendances supplémentaires qui nous aident à effectuer une quelques fonctions simples de GraphQL. Comme cela est courant avec le développement JavaScript moderne, vous n’avez pas besoin de toutes ces dépendances pour compléter la demande de données, mais elles aident certainement à donner au développeur une meilleure chance de structurer du code propre, facile à lire. Les dépendances dont vous avez besoin peuvent être installées en exécutant npm install --save apollo-boost. Réagit-apollo graphql-tag graphql .

Voici un aperçu de ces dépendances:

  • apollo- boost : une façon de commencer à utiliser GraphQL dans React / React Native
  • react-apollo : elle fournit une intégration entre GraphQL et le client Apollo
  • graphql-tag : balise littérale de modèle analysant les requêtes GraphQL
  • graphql : implémentation de référence JavaScript pour GraphQL

Une fois toutes les dépendances nécessaires installées, exécutez npm start . Vous devriez maintenant voir votre fenêtre d’exposition familière, et si vous lancez l’application (via un simulateur ou sur un appareil), vous devriez voir un écran semblable à celui-ci:

 Une maquette de notre page de démarrage . ]

En termes simples, cette application comporte deux écrans gérés par react-navigation Home.js et CoffeePage.js . L'écran Home contient une simple FlatList qui regroupe tous les grains de café fournis à son champ de données . Lorsque l'utilisateur clique dessus, l'utilisateur accède à CoffeePage pour cet élément, qui affiche davantage d'informations sur le produit. Il est de notre devoir de renseigner ces vues avec des données intéressantes provenant de GraphQL.

 La page complète du café

Apollo Server Playground

Toute transaction GraphQL réussie comporte deux éléments principaux: le serveur qui détient les données, et la requête frontale faisant la demande. Pour les besoins de ce didacticiel, nous n’allons pas nous plonger dans le monde merveilleux du code côté serveur, j’ai donc créé notre serveur prêt à l’emploi. Tout ce que vous avez à faire est de naviguer dans votre navigateur préféré vers yq42lj36m9.sse.codesandbox.io et de le laisser fonctionner tout au long du développement. Pour les personnes intéressées, le serveur lui-même fonctionne sous apollo-server et contient juste assez de code pour stocker les données dont nous avons besoin et les diffuser dès réception d'une requête appropriée. Pour en savoir plus, vous pouvez consulter apollographql.com pour en savoir plus sur apollo-server .

Principes de base de la requête GraphQL

Avant d'écrire le code réel Pour demander les données dont nous avons besoin pour notre application de comparaison des grains de café, nous devons comprendre le fonctionnement des requêtes GraphQL. Si vous connaissez déjà le fonctionnement des requêtes ou souhaitez simplement commencer à coder, passez à la section suivante.

Remarque: ces requêtes ne fonctionneront pas avec notre serveur codesandbox mais n'hésitez pas à créer le vôtre à codesandbox.io si vous souhaitez tester les requêtes.

À son niveau le plus simple, nous pouvons utiliser une structure plate pour nos requêtes lorsque nous connaître la forme des données que nous demandons:

 QUERY: RESPONSE:
{{
  café {"café": {
    mélange "mélange": "riche"
  }}
}}

À gauche, nous voyons la requête GraphQL demandant le champ blend de coffee . Cela fonctionne bien lorsque nous savons exactement quelle est notre structure de données, mais qu'en est-il lorsque les choses sont moins transparentes? Dans cet exemple, blend nous renvoie une chaîne, mais les requêtes peuvent également être utilisées pour demander des objets:

 QUERY: RESPONSE:
{{
  café {"café": {
    haricots {"haricots": [
        blend                               {
    }                                         blend: "rich"
  }                                         },
}                                           {
                                              blend: "smooth"
                                            }
                                          ]
                                        }
                                      }

Vous voyez ici que nous demandons simplement l'objet haricots seul le mélange du champ étant renvoyé de cet objet. Chaque objet du tableau de haricots peut très bien contenir d'autres données que le mélange mais les requêtes GraphQL nous aident à demander uniquement les données dont nous avons besoin, en supprimant toute information supplémentaire non nécessaire à notre base de données. application.

Alors qu’en est-il de la nécessité d’être plus précis que cela? GraphQL offre de nombreuses possibilités, mais les requêtes de données extrêmement puissantes permettent également de transmettre des arguments dans votre requête. Prenons l'exemple suivant:

 QUERY: RESPONSE:
{{
  café (companyId: "2") {"café": {
    haricots {"haricots": [
        blend                               {
    }                                         blend: "rich"
  }                                         },
}                                           {
                                              blend: "smooth"
                                            }
                                          ]
                                        }
                                      }

Ce que nous voyons, c'est que nous pouvons faire passer un argument – dans ce cas, le companyId – qui garantit que nous ne sommes renvoyés que des haricots d'une société en particulier. Avec REST, vous pouvez transmettre un seul ensemble d'arguments via des paramètres de requête et des segments d'URL, mais avec GraphQL interrogeant chaque champ, il peut obtenir son propre jeu d'arguments. Cela permet à GraphQL d’être une solution dynamique pour effectuer plusieurs extractions d’API par requête.

Alias ​​

Jusqu’à présent, le champ de l’objet renvoyé correspond au nom du champ dans la requête elle-même. C'est très bien lorsque vous utilisez des arguments simples, mais que se passe-t-il si vous souhaitez interroger le même champ avec des arguments différents dans votre demande de données? C'est ici que les alias entrent en jeu. Les alias vous permettent de modifier le nom d'un champ afin de pouvoir renommer les données renvoyées et donc utiliser des arguments différents dans votre demande de données. Prenons notre exemple de grain de café. Et si nous voulions renvoyer des données de deux identifiants de société différents? Nous structurerions notre requête de la manière suivante:

 QUERY: RESPONSE:
{{
  company1: café (companyId: "1") {"company1": {
    haricots {"haricots": [
      blend                                     {
    }                                             "blend": "rich"
  }                                             }
  company2: coffee(companyId: "2") {          ]
    des haricots {                                 },
      mélange "company2": {
    } "haricots": [
  }                                             {
}                                                 "blend": "fruity"
                                                }
                                              ]
                                            }
                                          }

Nous demandons ici des données pour les alias company1 et company2 qui sont simplement différentes requêtes de café empilées les unes sur les autres. Les alias peuvent être un outil puissant pour modifier vos besoins en fonction de vos exigences en matière de données.

Variables

Jusqu'à présent, nous connaissions notre requête exacte et nous pouvions donc la coder en dur dans notre application, mais la plupart des applications auront besoin de ces champs. être dynamique. Par exemple, l'utilisateur peut sélectionner une société de grains de café dans une liste à afficher. Nous ne savons pas à l’avance quelle entreprise de café en grains est sélectionnée par l’utilisateur. Nous avons donc besoin d’un moyen de satisfaire ces exigences. C’est là que les variables entrent en jeu.

La documentation de GraphQL répertorie trois opérations à effectuer pour utiliser des variables:

  • remplace la valeur statique dans la requête par $ nom_variable
  • déclare $ variableName en tant qu'une des variables acceptées par la requête
  • passez nomVariable: valeur dans le dictionnaire de variables distinct, spécifique au transport (généralement JSON)

Concrètement, cela signifie notre la requête de données ressemblera à quelque chose comme ceci:

 query coffeeCompany (companyId: CompanyId) {
    café (companyId: companyId) {
        des haricots: {
            type
        }
    }
}

Nous passerions également dans companyId en tant qu'objet JSON:

 {
    "companyId": "1"
}

L'utilisation de variables dans GraphQL est un moyen puissant de dynamiser toutes nos requêtes, car nous ne demandons que les données dont nous avons actuellement besoin.

Coffee Query

Pour les besoins de notre application, nous Nous aurons besoin d'une requête qui nous permette de demander des données pour récupérer uniquement nos grains de café, tout en incluant tous les champs pertinents dont nous aurons besoin. Nos exigences en matière de données ne sont pas si complexes, cela va donc ressembler à ceci:

 {
    café {
        des haricots {
            clé
            Nom
            prix
            mélange
            Couleur
            productImage
        }
    }
}

Demande de données

Passons maintenant au code que nous allons utiliser pour demander nos données. Ouvrez App.js qui contient toutes nos vues et sera un bon endroit pour faire notre demande de données lors du lancement de l'application.

Nous allons vouloir initialiser notre client. , ce que nous pouvons simplement faire en important ApolloClient à partir de apollo-boost et en spécifiant l'URL de notre serveur. Il est important de noter que vous devez initialiser le serveur. Pour ce faire, il vous suffit simplement d’exécuter yq42lj36m9.sse.codesandbox.io dans votre navigateur. Parfois, le serveur arrive à expiration. Si Expo renvoie un avertissement qui ressemble à une «erreur de réseau», rechargez yq42lj36m9.sse.codesandbox.io sur votre navigateur pour réinitialiser le serveur.

Une fois le serveur en marche, ajoutez les importations. et initialisation au sommet de App.js qui devrait ressembler à ceci:

 // ./App.js
importer ApolloClient à partir de 'apollo-boost';

client const = new ApolloClient ({uri: 'https://yq42lj36m9.sse.codesandbox.io/'})

Ensuite, nous voulons assembler la requête graphQL pour une utilisation ultérieure lorsque nous demandons nos données. Heureusement, la bibliothèque graphql-tag rend cela simple. De nouveau, nous devons importer la bibliothèque elle-même dans App.js :

 // ./App.js
importer le gql de 'graphql-tag';

Nous pouvons maintenant structurer la requête:

 // ./App.js
const QUERY = gql`
{
    café {
        des haricots {
            clé
            Nom
            prix
            mélange
            Couleur
            productImage
        }
    }
}
`

L'étape suivante consiste à modifier la fonction de rendu pour inclure notre demande de données. Pour ce faire, nous utilisons la bibliothèque react-apollo pour formuler la demande, ce qui nous permet de gérer la réponse à notre guise. Ajouter une nouvelle importation à App.js :

 // ./App.js
import {ApolloProvider, Query} de 'react-apollo';

Modifiez ensuite la fonction de rendu afin qu'elle ressemble à ceci:

 // ./App.js
render () {
    revenir (
    
        
         {({chargement, erreur, données}) => {
            if (loading || error) return 
            retour 
            {this.state.isFontsLoaded? : }
            
        }}
        
    
    );
}

Vous voyez ici que nous utilisons le QUERY que nous avons créé précédemment pour demander les données nécessaires. Pour le moment, nous affichons simplement une vue vide lors du chargement et en cas d'erreur dans la demande de données. En pratique, cette option serait remplacée par les vues de chargement et d'erreur correspondantes, mais pour cet exemple, nous les laisserons vides. Une fois les données renvoyées, nous rendons notre AppContainer comme d'habitude. Vous pouvez vérifier que des données parviennent en vérifiant que les données ont bien été renvoyées. Cela peut être vérifié en ajoutant un console.log (data) à votre code pour afficher la sortie dans votre terminal. Vous devriez recevoir un objet avec nos champs café et haricots tant que votre serveur Apollo s'exécute sans problème.

Stockage de données avec l'API contextuelle

Nous ' Nous allons avoir besoin d’un endroit pour stocker nos données qui seront accessibles dans l’un de nos composants, quelle que soit leur distance dans l’arbre. Si nous devions transmettre les données à plusieurs enfants uniquement pour accéder à notre composant, ce ne serait pas la solution la plus efficace. Étant donné que nos besoins en stockage de données sont relativement simples pour cet exemple, il serait bon d’utiliser l’API contextuelle de React plutôt que de recourir à un outil de gestion d’état plus complexe comme Redux. L'API de contexte vous permet de transmettre l'état global de notre arborescence de composants sans qu'il soit nécessaire de le faire à chaque fois, ce qui est suffisant pour notre exemple actuel.

Les avantages de Redux au-dessus de l'API de contexte peuvent être globalement réduits.

  • Redux est livré avec un débogueur qui voyage dans le temps
  • il fournit au développeur des API de middleware, vous donnant accès à des outils tels que redux-sagas
  • ses liaisons React évitent d'avoir trop de rendus [19659021] L'utilisation de l'API de contexte ne pourrait être plus simple. En substance, nous devons simplement créer un composant pour stocker toutes nos données et accéder aux données en créant un composant lorsque nous en avons besoin.

    Création d'un fournisseur

    Revenons en arrière. to App.js où nous n'avons qu'à ajouter quelques lignes pour que notre Provider soit opérationnel. Premièrement, nous allons commencer par créer notre AppContext . Nous devons accéder à cela dans tout fichier dans lequel nous voulons utiliser les données stockées. Nous devons donc nous assurer qu’elles sont exportées. Pour créer le AppContext ajoutez la ligne suivante à App.js :

     // ./App.js
    export const AppContext = React.createContext ({données: {café: {beans: []}}});
    

    Nous créons ici le contexte et l’initialisons avec des données vierges. Ensuite, nous voulons renseigner le AppProvider avec les données que nous recevons du serveur GraphQL.

    Stockage des données cCoffee

    Pour mettre à jour notre fournisseur avec les données, nous devons simplement changer le vue de conteneur vide dans notre App.js fonctionne pour le fournisseur tout en ajoutant nos données GraphQL à ses données prop. Cela ressemble à ceci:

     // ./App.js
    render () {
        revenir (
            
            
             {({chargement, erreur, données}) => {
                if (loading || error) return 
                retour 
                    {this.state.isFontsLoaded? : }
                
                }}
            
            
        );
    }
    

    Ici, vous pouvez voir que nous stockons directement les données de bean ( de data.coffee.beans ) chez notre fournisseur. À ce stade, nous disposons de toutes les données nécessaires, mais nous restons en train de restituer notre contenu d’espace réservé. La dernière pièce de ce puzzle est de modifier Home.js pour rendre nos données à l'aide d'un consommateur .

    Création d'un consommateur d'appli

    Tout d'abord, nous devons importer notre AppContext de plus tôt pour utiliser le consommateur . Pour ce faire, nous devons simplement l'importer de App.js à Home.js :

     // ./src/Home.js
    importer {AppContext} de '../App';
    

    L'utilisation d'un consommateur fonctionne comme n'importe quel autre composant React. Pour les besoins actuels, nous l’ajouterons à notre fonction de rendu et nous utiliserons les données pour renseigner notre listeListe . Notre fonction de rendu devrait ressembler à ceci:

     // ./src/Home.js
    render () {
        revenir (
            
            {
                (contexte) =>
                
                    
                    
                     CAFE 
                     SÉLECTION 
                    
                       this.props.navigation.navigate ('CoffeePage', {item: item})}>
                        
                         {item.name} 
                         {item.price} 
                    }
                    numColumns = {2}
                    />
                
            }
            
        )
    }
    

    Si nous examinons le code ci-dessus, vous pouvez voir que AppContext.Consumer nous fournit un contexte qui contient nos données GraphQL. Nous utilisons ce contexte pour peupler le composant FlatList en le transmettant aux données prop. Lorsque l'utilisateur clique sur l'un des articles de café, nos données sont transmises via nos paramètres de navigation à notre CoffeePage.js ce qui permet d'y accéder dans cette vue. Si vous enregistrez maintenant vos fichiers modifiés et lancez l'application sur Expo, vous devriez voir votre FlatList entièrement peuplée.

     L'application terminée

    Résumé

    Félicitations! Vous avez utilisé avec succès GraphQL pour récupérer des données et les restituer à l’aide de React Native. Nous avons appris à quel point les requêtes GraphQL peuvent être puissantes, tout en soulignant les avantages par rapport à un système tel que REST. Je vous encourage à utiliser GraphQL dans votre prochain projet et à juger par vous-même de la rapidité avec laquelle il est possible de récupérer des données, en particulier dans les applications riches en données.

    Si vous souhaitez explorer GraphQL plus en détail, je vous recommande de lire le « Queries and Mutations ”de la documentation GraphQL, et commencez peut-être à coder vous-même un serveur Apollo à l'aide de codesandbox.io .

    Le code complet de ce projet est disponible sur . ] GitHub alors n'hésitez pas à cloner / transformer le référentiel et à apporter vos propres améliorations!




Source link