Coder une application avec GraphQL, React Native et AWS AppSync l'application

Ce que vous allez créer

Dans ces tutoriels, je vous montre comment créer et interagir avec une base de données GraphQL à l'aide de AWS AppSync et de React Native. Cette application aura des fonctionnalités en temps réel et hors connexion, ce que nous obtenons avec AppSync.. 

Dans l'article précédent, nous avons configuré notre back-end GraphQL avec le service Amazon AppSync. Vérifiez si vous ne l'avez pas déjà fait. Ou, si vous souhaitez une introduction à GraphQL, jetez un œil à certains de nos autres articles..

Dans cet article, nous allons tout finir en décrivant la construction du client React Native. Le projet est un peu trop compliqué pour vous guider étape par étape, mais je vais vous expliquer l'architecture du projet et vous montrer les éléments clés du code source..

Présentation de l'architecture des applications et de la structure des dossiers

Notre application aura un point d’entrée principal composé de deux vues en onglets. Un onglet listera les villes de notre base de données GraphQL, et l’autre sera le formulaire de saisie permettant d’ajouter une nouvelle ville. le Villes onglet sera un navigateur qui permettra à l'utilisateur de naviguer vers les villes individuelles.

Nous allons stocker les composants principaux dans le la source dossier, et aura d'autres dossiers dans le src répertoire pour contenir nos mutations, requêtes et abonnements GraphQL.

Nous aurons aussi un les atouts dossier pour contenir nos images.

Création et configuration du client natif React

Pour référence, jetez un coup d'œil au code final de cette application dans le référentiel du tutoriel GitHub, mais je vais décrire certaines des étapes que j'ai suivies pour créer l'application à partir de zéro..

Tout d'abord, nous avons créé une nouvelle application React Native à l'aide d'Expo. 

Une fois dans le projet nouvellement créé, nous avons installé nos dépendances. Pour les fonctionnalités GraphQL et AppSync, nous avons utilisé les dépendances suivantes:

aws-appsync aws-appsync-réagir graphql-tag react-apollo uuid

Nous avons également utilisé les dépendances suivantes pour la conception de l'interface utilisateur:

réaction-navigation réaction-éléments-natifs réaction-icônes-vectorielles-natif

De plus, une fois la bibliothèque Vector Icons installée, nous l’avons liée:

réagir-lien natif réagir-icônes vectorielles natif

Après avoir installé nos dépendances, nous avons téléchargé le AppSync.js fichier de notre console AppSync. Dans notre console de projet AppSync, nous avons choisi Réagir Natif en bas, et cliqué sur l'orange Télécharger bouton pour télécharger ce fichier de configuration.


Ce fichier de configuration contient les informations du client AppSync dont nous avions besoin pour créer un nouveau client.. 

Configuration du fournisseur et du magasin

Le niveau supérieur de l'application correspond à l'emplacement où nous effectuerons notre configuration pour connecter l'API AppSync au client React Native..Si vous avez déjà utilisé Redux ou React Apollo auparavant, tout cela vous sera familier. Si ce n’est pas le cas, n’oubliez pas que tout enfant d’un enfant Fournisseur, dans notre cas la ApolloProvider, aura accès à sa fonctionnalité donnée. 

Le code suivant est notre nouveau App.js fichier, qui est le composant principal importé de notre index.js point d'accès.

import Réagissez à partir de 'réagir' importez des onglets à partir de './src/Tabs' importez AWSAppSyncClient à partir de "aws-appsync"; importer réhydraté de 'aws-appsync-react'; importer ApolloProvider de 'react-apollo'; importer appSyncConfig à partir de './aws-exports'; client const = new AWSAppSyncClient (url: appSyncConfig.graphqlEndpoint, région: appSyncConfig.region, auth: type: appSyncConfig.authType, apiKey: appSyncConfig.apiKey,); const WithProvider = () => (      ) exporter par défaut avec le fournisseur

Dans ce fichier, nous configurons un nouveau client AppSync en combinant les éléments suivants: AWSAppSyncClient constructeur de aws-appsync ainsi que la configuration dans notre aws-exports.js fichier, qui fournit l'URL, la région, le type d'authentification et la clé d'API d'authentification de GraphQL.

Nous emballons ensuite notre principal point d’entrée, le Tabs.js fichier qui tiendra notre navigation onglet, dans un ApolloProvider et transmettez le client AppSync en tant que prop client. Nous emballons aussi le Onglets composant dans un Réhydraté composant que nous importons aws-appsync-react. Cela garantira que nous avons lu le stockage async et que nous avons réhydraté notre cache avant de rendre l'interface utilisateur..

Désormais, notre application pourra interroger les données de notre terminal AppSync et également effectuer des mutations et des abonnements.!

La navigation

Le point d'entrée principal de l'application est une navigation par onglets, implémentée dans le fichier Tabs.js avec React Navigation..

Ce que nous avons fait ici est de créer et d’exporter une TabNavigator avec deux onglets. Ceux-ci sont:

  1. Villes: Ce composant répertorie nos villes et constitue un composant de navigation en soi. Ce composant est un navigateur car nous voulons pouvoir naviguer dans chaque ville et voir les emplacements dans la ville..
  2. AddCity: Ce composant est un formulaire pour que nous puissions ajouter de nouvelles villes.

Composants réutilisables

Cette application a un seul composant réutilisable, un personnalisé Saisie de texte. Étant donné que nous allons dupliquer ce style et cette fonctionnalité à plusieurs reprises, nous avons décidé d'en faire son propre composant. Le composant d’entrée est implémenté dans Input.js.

Liste des villes et navigation urbaine

La vue principale de l'application est une liste des villes que nous allons récupérer à partir de GraphQL. Nous voulons pouvoir naviguer depuis chaque ville répertoriée vers une vue détaillée de cette ville où nous pouvons ajouter des emplacements..

Pour ce faire, nous faisons Cities.js son propre StackNavigator, et City.js le composant auquel nous accédons lorsque nous choisissons une ville. En cliquant sur une ville en Villes, nous passons son nom et son identifiant comme accessoires à Ville.

Cities.js

Dans ce composant, nous allons chercher en utilisant le listCities requête, et nous souscrivons également à la NewCitySubscription, Ainsi, lorsqu'une nouvelle ville est ajoutée, même à partir d'un autre client, nous allons gérer cet abonnement et mettre à jour notre éventail de villes. le listCities requête rend un tableau de villes disponible dans notre composant en tant que this.props.cities.

City.js

Dans cette composante, nous sommes passés d'une ville comme accessoires de navigation (disponible en tant que props.navigation.state.params.city). Nous utilisons la ville identifiant valeur pour aller chercher la liste des emplacements pour la ville choisie en utilisant le listLocations question. Nous nous abonnons à de nouveaux emplacements de la même manière que nos abonnés à de nouvelles villes Cities.js, en utilisant le NewLocationSubscription abonnement. Nous fournissons également Réponse optimiste et mettre à jour fonctions pour quand une nouvelle ville est ajoutée. 

Ajout de villes

Enfin, nous devons implémenter la fonctionnalité permettant d’ajouter de nouvelles villes à notre API GraphQL dans le fichier AddCity.js. Pour ce faire, nous avons câblé une mutation avec un formulaire qui appellera createCity, passer la valeur de la saisie de formulaire.

AddCity a un onAdd fonction que nous définissons dans notre composition GraphQL, qui écrit non seulement une nouvelle ville dans notre base de données GraphQL, mais implémente également une interface utilisateur optimiste utilisant une combinaison de: Réponse optimiste et mettre à jour.

Mutations, requêtes et abonnements

Les mutations, les requêtes et les abonnements constituent la fonctionnalité essentielle de l'intégration avec notre API GraphQL. Dans notre application, cette fonctionnalité est implémentée dans le Cities.js, City.js, et AddCity.js fichiers utilisant le client AppSync.

Regardons de plus près comment les mutations, les requêtes et les abonnements sont implémentés dans notre code.

Des requêtes

Tout d’abord, voyons comment créer et exporter une requête GraphQL pouvant interagir avec le listCities requête dans notre schéma AppSync. Ce code est contenu dans le src / queries / ListCities.js fichier.

importer le gql de 'graphql-tag'; export gql par défaut 'requête listCities listCities items nom id pays' 

Ensuite, nous importons cette requête dans le Cities.js déposer, avec quelques aides de réagir-apollo, et câbler le composant que nous aimerions avoir accès à ces données en utilisant composer et graphql de réagir-apollo.

import compose, graphql de 'react-apollo' import ListCities de la classe './queries/ListCities' Les villes étend React.Component // la définition de la classe ici // a maintenant accès à this.props.cities export default compos ( graphql (ListCities, props: props => (villes: props.data.listCities? props.data.listCities.items: [],))) (CityList)

Nous avons maintenant accès au tableau cities de notre serveur GraphQL en tant qu’appui. On peut utiliser this.props.cities mapper sur le tableau des villes provenant de GraphQL.

Mutations

Pour créer une mutation, nous devons d’abord créer une mutation GraphQL de base et l’exporter. Nous faisons cela dans le src / mutations / CreateCity.js fichier.

importer le gql de 'graphql-tag' le gql par défaut d'exportation 'mutation addCity ($ name: String !, $ country: String !, $ id: ID!) createCity (entrée: nom: $ name, pays: $ pays, id : $ id) nom id pays ' 

Maintenant, nous pouvons importer cette mutation (avec les aides Apollo) dans le AddCity.js fichier et l'utiliser dans un composant: 

import compose, graphql de 'react-apollo' import AddCityMutation de la classe './mutations/AddCity' AddCity étend React.Component // la définition de la classe ici // a maintenant accès à this.props.onAdd () export default compose (graphql (AddCityMutation, props: props => (onAdd: city => props.mutate (variables: city)))) (AddCity) 

Maintenant, nous avons accès à un accessoire appelé onAdd, que nous passons un objet que nous aimerions envoyer à la mutation!

Abonnements

Les abonnements nous permettent de souscrire aux modifications de données et de les mettre à jour dans notre application en temps réel. Si nous devions modifier notre base de données en ajoutant ou en supprimant une ville, nous souhaiterions que notre application soit mise à jour en temps réel..

Premièrement, nous devons créer la mutation et l'exporter afin de pouvoir y accéder via le client. Nous sauvons cela dans le src / subscriptionsNewCitySubscriptions.js fichier.

importer un gql à partir de 'graphql-tag' exporter un gql par défaut 'NewCitySub onCreateCity nom du pays'; 

Nous pouvons maintenant importer et joindre l’abonnement dans Cities.js. Nous avons déjà examiné comment extraire les villes de notre API. Mettons maintenant à jour cette fonctionnalité pour souscrire aux nouvelles modifications et mettre à jour le tableau de villes quand une nouvelle ville est ajoutée..

importer AllCity depuis './queries/AllCity' importer NewCitiesSubscription depuis './subscriptions/NewCitySubscription'; importer composer, graphql de la classe 'react-apollo' Les villes étendues React.Component composantWillMount () this.props.subscribeToNewCities ();  render () // reste du composant ici export par défaut compose (graphql (ListCities, options: fetchPolicy: 'cache-and-network', props: (props) => return villes: props. data.listCities? props.data.listCities.items: [], subscribeToNewCities: params => props.data.subscribeToMore (document: NewCitiesSubscription, updateQuery: (précedent, subscriptionData: data: onCreateCity : onCreateCity)): > return … prev, listCities: __typename: 'CityConnection', éléments: [onCreateCity,… prev.listCities.items.filter (city => city.id! == onCreateCity.id)])   ) )(Villes)

Nous ajoutons un nouvel accessoire appelé subscribeToNewCities, que nous appelons composantDidMount. Dans la souscription, nous transmettons un document (la définition de la souscription) et updateQuery pour décrire ce que nous voulons qu'il se passe quand cela met à jour.

Nous destructure createCity (contenant la mutation) des accessoires qui sont passés dans le updateQuery fonction et renvoyer toutes les valeurs existantes avec un listCities  tableau contenant les villes précédentes avec les nouvelles données de la ville que nous recevons de createCity.

UI optimiste

Et si nous ne voulions pas attendre que l'abonnement renvoie les données les plus récentes de notre API afin de mettre à jour notre interface utilisateur?

Si un utilisateur crée une nouvelle ville, nous voulons l'ajouter automatiquement au tableau de villes et le rendre dans notre application avant de recevoir la confirmation du service d'arrière-plan..

Nous pouvons le faire facilement en utilisant quelques techniques et fonctions.

Mettons à jour notre AddCityMutation à ce qui suit (vous pouvez voir ce code dans le fichier source AddCity.js):

import compose, graphql de 'react-apollo' import AddCityMutation de la classe './mutations/AddCity' AddCity étend React.Component // la définition de la classe ici // a maintenant accès à this.props.onAdd () export default compose (graphql (AddCityMutation, props: props => (onAdd: ville => props.mutate (variables: ville, optimisteRéponse: __typename: 'Mutation' , update: (proxy, data: createCity) => const data = proxy.readQuery (requête: ListCities); data.listCities.items.unshift (createCity); proxy.writeQuery (requête: ListCities , data);)))) (AddCity) 

Ici, nous avons ajouté deux nouvelles propriétés à l'objet argument de la fonction mutate:

  1. Réponse optimiste définit la nouvelle réponse que vous souhaitez avoir dans la fonction de mise à jour.
  2. mettre à jour prend deux arguments, le proxy (qui vous permet de lire dans le cache) et les données que vous souhaitez utiliser pour effectuer la mise à jour. Nous lisons le cache actuel (proxy.readQuery), ajoutez-y notre nouvel élément au tableau des éléments, puis écrivez dans le cache, ce qui a mis à jour notre interface utilisateur..

Conclusion

GraphQL est de plus en plus courant. Une grande partie de la complexité entourant GraphQL est liée à la gestion du back-end et de la couche API. Cependant, des outils tels que AppSync suppriment cette complexité, évitant aux développeurs de passer plus de temps à configurer et à travailler sur le serveur..

J'ai hâte de voir beaucoup plus d'innovations dans ce domaine et je suis impatient de voir ce que nous verrons d'autre en 2018.!

Si vous souhaitez utiliser AppSync avec le framework Serverless, consultez cette excellente introduction à l’utilisation conjointe des deux..

Si vous souhaitez en savoir plus sur AWS AppSync, je vous suggère de consulter la page d'accueil AppSync et la documentation permettant de créer un client GraphQL..

Si vous souhaitez contribuer à ce projet, vous pouvez vous connecter à notre référentiel GitHub. Si vous avez des idées, n'hésitez pas à nous envoyer un PR ou à utiliser cette application pour démarrer votre prochain projet React Native GraphQL!

Et en attendant, consultez certains de nos autres tutoriels React Native ici sur Envato Tuts+!