GraphQL - Guide rapide

GraphQL est une technologie open source côté serveur qui a été développée par Facebook pour optimiser les appels d'API RESTful. C'est un moteur d'exécution et un langage de requête de données. Dans ce chapitre, nous discutons des avantages de l'utilisation de GraphQL.

Pourquoi GraphQL

Les API RESTful suivent une approche claire et bien structurée axée sur les ressources. Cependant, lorsque les données deviennent plus complexes, les itinéraires s'allongent. Parfois, il n'est pas possible de récupérer des données avec une seule requête. C'est là que GraphQL est utile. GraphQL structure les données sous la forme d'un graphe avec sa puissante syntaxe de requête pour parcourir, récupérer et modifier les données.

Voici les avantages de l'utilisation du langage de requête GraphQL -

Demandez ce que vous voulez et obtenez-le

Envoyez une requête GraphQL à votre API et obtenez exactement ce dont vous avez besoin. Les requêtes GraphQL renvoient toujours des résultats prévisibles. Les applications utilisant GraphQL sont rapides et stables. Contrairement aux services Restful, ces applications peuvent restreindre les données qui doivent être extraites du serveur.

L'exemple suivant vous aidera à mieux comprendre cela -

Considérons un objet métier Student avec les attributs id, firstName, lastName et collegeName . Supposons qu'une application mobile ait besoin de récupérer uniquement le prénom et l' ID . Si nous concevons un point de terminaison REST comme / api / v1 / Students , il finira par récupérer les données pour tous les champs d'un objet étudiant . Cela signifie que les données sont surexplorées par le service RESTful. Ce problème peut être résolu en utilisant GraphQL.

Considérez la requête GraphQL donnée ci-dessous -

{
   students {
      id
      firstName
   }
}

Cela renverra des valeurs uniquement pour les champs id et firstname. La requête ne récupérera pas les valeurs des autres attributs de l'objet étudiant. La réponse à la requête illustrée ci-dessus est la suivante:

{
   "data": {
      "students": [
         {
            "id": "S1001",
            "firstName": "Mohtashim"
         },
         {
            "id": "S1002",
            "firstName": "Kannan"
         }
      ]
   }
}

Obtenez de nombreuses ressources en une seule demande

Les requêtes GraphQL aident à récupérer en douceur les objets métier associés, tandis que les API REST classiques nécessitent un chargement à partir de plusieurs URL. Les API GraphQL récupèrent toutes les données dont votre application a besoin en une seule requête. Les applications utilisant GraphQL peuvent être rapides même sur des connexions de réseau mobile lentes.

Considérons un autre objet métier, College, qui a les attributs: nom et emplacement. L' objet métier Student a une relation d'association avec l'objet College. Si nous devions utiliser une API REST pour récupérer les détails des étudiants et de leur collège, nous finirions par faire deux requêtes au serveur comme / api / v1 / étudiants et / api / v1 / colleges . Cela entraînera une sous-extraction des données à chaque demande. Les applications mobiles sont donc obligées de passer plusieurs appels vers le serveur pour obtenir les données souhaitées.

Cependant, l'application mobile peut récupérer les détails des objets Student et College en une seule requête à l'aide de GraphQL.

Ce qui suit est une requête GraphQL pour récupérer des données -

{
   students{
      id
      firstName
      lastName
      college{
         name
         location
      }
   }
}

La sortie de la requête ci-dessus contient exactement les champs que nous avons demandés comme indiqué ci-dessous -

{
   "data": {
      "students": [
         {
            "id": "S1001",
            "firstName": "Mohtashim",
            "lastName": "Mohammad",
            "college": {
               "name": "CUSAT",
               "location": "Kerala"
            }
         },
         
         {
            "id": "S1002",
            "firstName": "Kannan",
            "lastName": "Sudhakaran",
            "college": {
               "name": "AMU",
               "location": "Uttar Pradesh"
            }
         },
         
         {
            "id": "S1003",
            "firstName": "Kiran",
            "lastName": "Panigrahi",
            "college": {
               "name": "AMU",
               "location": "Uttar Pradesh"
            }
         }
      ]
   }
}

Décrivez ce qui est possible avec un système de typage

GraphQL est fortement typé et les requêtes sont basées sur des champs et leurs types de données associés. En cas de non-concordance de type dans une requête GraphQL, les applications serveur renvoient des messages d'erreur clairs et utiles. Cela permet un débogage fluide et une détection facile des bogues par les applications clientes. GraphQL fournit également des bibliothèques côté client qui peuvent aider à réduire la conversion et l'analyse de données explicites.

Un exemple des types de données Étudiant et Collège est donné ci-dessous -

type Query {
   students:[Student]
}

type Student {
   id:ID!
   firstName:String
   lastName:String
   fullName:String
   college:College
}

type College {
   id:ID!
   name:String
   location:String
   rating:Float
   students:[Student]
}

Passez plus vite avec de puissants outils de développement

GraphQL fournit des outils de développement riches pour la documentation et le test des requêtes. GraphiQL est un excellent outil qui génère de la documentation de la requête et de son schéma. Il fournit également un éditeur de requêtes pour tester les API GraphQL et une capacité de complétion de code intelligente lors de la création de requêtes.

Dans ce chapitre, nous découvrirons la configuration environnementale de GraphQL. Pour exécuter les exemples de ce didacticiel, vous aurez besoin des éléments suivants:

  • Un ordinateur exécutant Linux, macOS ou Windows.

  • Un navigateur Web, de préférence la dernière version de Google Chrome.

  • Une version récente de Node.js installée. La dernière version LTS est recommandée.

  • Visual Studio Code avec l'extension GraphQL pour VSCode installé ou tout éditeur de code de votre choix.

Comment créer un serveur GraphQL avec Nodejs

Nous allons passer par une approche détaillée par étapes pour construire un serveur GraphQL avec Nodejs comme indiqué ci-dessous -

Étape 1 - Vérifier les versions de nœud et de Npm

Après avoir installé NodeJs, vérifiez la version de node et npm à l'aide des commandes suivantes sur le terminal -

C:\Users\Admin>node -v
v8.11.3

C:\Users\Admin>npm -v
5.6.0

Étape 2 - Créer un dossier de projet et ouvrir dans VSCode

Le dossier racine du projet peut être nommé test-app.

Ouvrez le dossier à l'aide de l'éditeur de code Visual Studio en suivant les instructions ci-dessous -

C:\Users\Admin>mkdir test-app
C:\Users\Admin>cd test-app
C:\Users\Admin\test-app>code.

Étape 3 - Créez package.json et installez les dépendances

Créez un fichier package.json qui contiendra toutes les dépendances de l'application serveur GraphQL.

{
   "name": "hello-world-server",
   "private": true,
   "scripts": {
      "start": "nodemon --ignore data/ server.js"
   },
   
   "dependencies": {
      "apollo-server-express": "^1.4.0",
      "body-parser": "^1.18.3",
      "cors": "^2.8.4",
      "express": "^4.16.3",
      "graphql": "^0.13.2",
      "graphql-tools": "^3.1.1"
   },
   
   "devDependencies": {
      "nodemon": "1.17.1"
   }
}

Installez les dépendances en utilisant la commande comme indiqué ci-dessous -

C:\Users\Admin\test-app>npm install

Étape 4 - Créer une base de données de fichiers plats dans le dossier de données

Dans cette étape, nous utilisons des fichiers plats pour stocker et récupérer des données. Créez un dossier de données et ajoutez deux fichiersstudents.json et colleges.json.

Voici le colleges.json fichier -

[
   {
      "id": "col-101",
      "name": "AMU",
      "location": "Uttar Pradesh",
      "rating":5.0
   },
   
   {
      "id": "col-102",
      "name": "CUSAT",
      "location": "Kerala",
      "rating":4.5
   }
]

Voici le students.json fichier -

[
   {
      "id": "S1001",
      "firstName":"Mohtashim",
      "lastName":"Mohammad",
      "email": "[email protected]",
      "password": "pass123",
      "collegeId": "col-102"
   },
   
   {
      "id": "S1002",
      "email": "[email protected]",
      "firstName":"Kannan",
      "lastName":"Sudhakaran",
      "password": "pass123",
      "collegeId": "col-101"
   },
   
   {
      "id": "S1003",
      "email": "[email protected]",
      "firstName":"Kiran",
      "lastName":"Panigrahi",
      "password": "pass123",
      "collegeId": "col-101"
   }
]

Étape 5 - Créer une couche d'accès aux données

Nous devons créer un magasin de données qui charge le contenu du dossier de données. Dans ce cas, nous avons besoin de variables de collecte, étudiants et collèges . Chaque fois que l'application a besoin de données, elle utilise ces variables de collecte.

Créez le fichier db.js avec dans le dossier du projet comme suit -

const { DataStore } = require('notarealdb');

const store = new DataStore('./data');

module.exports = {
   students:store.collection('students'),
   colleges:store.collection('colleges')
};

Étape 6 - Créer un fichier de schéma, schema.graphql

Créez un fichier de schéma dans le dossier de projet actuel et ajoutez le contenu suivant -

type Query  {
   test: String
}

Étape 7 - Créer un fichier de résolution, resolvers.js

Créez un fichier de résolution dans le dossier du projet actuel et ajoutez le contenu suivant -

const Query = {
   test: () => 'Test Success, GraphQL server is up & running !!'
}
module.exports = {Query}

Étape 8 - Créez Server.js et configurez GraphQL

Créez un fichier serveur et configurez GraphQL comme suit -

const bodyParser = require('body-parser');
const cors = require('cors');
const express = require('express');
const db = require('./db');

const port = process.env.PORT || 9000;
const app = express();

const fs = require('fs')
const typeDefs = fs.readFileSync('./schema.graphql',{encoding:'utf-8'})
const resolvers = require('./resolvers')

const {makeExecutableSchema} = require('graphql-tools')
const schema = makeExecutableSchema({typeDefs, resolvers})

app.use(cors(), bodyParser.json());

const  {graphiqlExpress,graphqlExpress} = require('apollo-server-express')
app.use('/graphql',graphqlExpress({schema}))
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))

app.listen(
   port, () => console.info(
      `Server started on port ${port}`
   )
);

Étape 9 - Exécutez l'application et testez avec GraphiQL

Vérifiez la structure des dossiers du projet test-app comme suit -

test-app /
   -->package.json
   -->db.js
   -->data
      students.json
      colleges.json
   -->resolvers.js
   -->schema.graphql
   -->server.js

Exécutez la commande npm start comme indiqué ci-dessous -

C:\Users\Admin\test-app>npm start

Le serveur fonctionne sur le port 9000, nous pouvons donc tester l'application à l'aide de l'outil GraphiQL. Ouvrez le navigateur et entrez l'URL http: // localhost: 9000 / graphiql. Tapez la requête suivante dans l'éditeur -

{
   Test 
}

La réponse du serveur est donnée ci-dessous -

{
   "data": {
      "test": "Test Success, GraphQL server is running !!"
   }
}

GraphQL est une spécification qui décrit le comportement d'un serveur GraphQL. Il s'agit d'un ensemble de directives sur la manière dont les demandes et les réponses doivent être traitées comme les protocoles pris en charge, le format des données pouvant être acceptées par le serveur, le format de la réponse renvoyée par le serveur, etc. La requête faite par un client au GraphQL serveur est appelé une requête. Un autre concept important de GraphQL est ses agnostiques de couche de transport. Il peut être utilisé avec n'importe quel protocole réseau disponible comme TCP, websocket ou tout autre protocole de couche de transport. Il est également neutre pour les bases de données, vous pouvez donc l'utiliser avec des bases de données relationnelles ou NoSQL.

GraphQL Server peut être déployé en utilisant l'une des trois méthodes répertoriées ci-dessous -

  • Serveur GraphQL avec base de données connectée
  • Serveur GraphQL qui intègre les systèmes existants
  • Approche hybride

Serveur GraphQL avec base de données connectée

Cette architecture dispose d'un serveur GraphQL avec une base de données intégrée et peut souvent être utilisée avec de nouveaux projets. À la réception d'une requête, le serveur lit la charge utile de la requête et récupère les données de la base de données. Cela s'appelle la résolution de la requête. La réponse renvoyée au client respecte le format spécifié dans la spécification officielle GraphQL.

Dans le diagramme ci-dessus, le serveur GraphQL et la base de données sont intégrés sur un seul nœud. Le client (bureau / mobile) communique avec le serveur GraphQL via HTTP. Le serveur traite la demande, récupère les données de la base de données et les renvoie au client.

GraphQL Server intégrant les systèmes existants

Cette approche est utile pour les entreprises disposant d'une infrastructure existante et de différentes API. GraphQL peut être utilisé pour unifier les microservices, l'infrastructure héritée et les API tierces dans le système existant.

Dans le diagramme ci-dessus, une API GraphQL agit comme une interface entre le client et les systèmes existants. Les applications clientes communiquent avec le serveur GraphQL qui à son tour résout la requête.

Approche hybride

Enfin, nous pouvons combiner les deux approches ci-dessus et construire un serveur GraphQL. Dans cette architecture, le serveur GraphQL résoudra toute requête reçue. Il récupérera les données de la base de données connectée ou des API intégrées. Ceci est représenté dans la figure ci-dessous -

Ce chapitre traite des différents composants GraphQL et de la manière dont ils communiquent entre eux. Les composants d'application entiers peuvent être distingués comme ci-dessous -

  • Composants côté serveur
  • Composants côté client

Composants côté serveur

Le serveur GraphQL constitue le composant principal côté serveur et permet d'analyser les requêtes provenant des applications client GraphQL. Apollo Server est l'implémentation la plus couramment utilisée de la spécification GraphQL. Les autres composants de programmation de serveur comprennent les éléments suivants:

Sr.No. Éléments essentiels et description du serveur
1

Schema

Un schéma GraphQL est au centre de toute implémentation de serveur GraphQL et décrit les fonctionnalités disponibles pour les clients qui s'y connectent.

2

Query

Une requête GraphQL est la demande de l'application cliente pour récupérer des données de la base de données ou des API héritées.

3

Resolver

Les résolveurs fournissent les instructions pour transformer une opération GraphQL en données. Ils résolvent la requête en données en définissant des fonctions de résolution.

Composants côté client

Vous trouverez ci-dessous les composants côté client -

Sr.No. Outil et description
1

GraphiQL

Interface basée sur un navigateur pour l'édition et le test des requêtes et des mutations GraphQL.

2

ApolloClient

Meilleur outil pour créer des applications clientes GraphQL. S'intègre bien avec tous les frontaux javascript.

Le diagramme ci-dessous montre un Client-Server architecture. Le serveur Web est construit sur NodeJs et le framework Express. Une demande est adressée au serveur Apollo GraphQL par l'application ReactJS (construite à l'aide de la bibliothèque Apollo Client) ou par l'application de navigateur GraphiQL. La requête sera analysée et validée par rapport à un schéma défini dans le serveur. Si le schéma de requête réussit la validation, les fonctions de résolveur associées seront exécutées. Le résolveur contiendra du code pour récupérer les données d'une API ou d'une base de données.

Dans ce chapitre, nous allons créer une API simple qui renvoie un message d'accueil, HelloWorld, et y accéder à l'aide de GraphiQL.

Exemple

Cet exemple est basé sur les serveurs NodeJS, Express et Apollo. Nous apprendrons à rassembler tous les concepts avec les étapes suivantes -

Étape 1 - Configuration d'Express

ExpressJS est un cadre d'application Web qui aide à créer des sites Web et des applications Web. Dans cet exemple, nous allons créer une API GraphQL au-dessus du framework Express.

La prochaine étape consiste à créer un dossier hello-world-serveret accédez au même dossier depuis le terminal. Ajoutez package.json et donnez un nom au package. Comme ce package n'est utilisé qu'en interne, nous pouvons le déclarer privé.

{
   "name":"hello-world-server",
   "private":true
}

Installez les dépendances pour le serveur Express comme indiqué ci-dessous -

C:\Users\Admin\hello-world-server>npm install express body-parser cors

body-parser est un package middleware qui aide Express à gérer efficacement les requêtes HTTP Post. cors est un autre package middleware qui gère le partage de ressources entre origines.

Créer un server.js dans le dossier du projet et tapez ce qui suit -

const bodyParser = require('body-parser')
   const cors = require('cors')
   const express = require('express')
   const port = process.env.PORT|| 9000
   const app = express()
   
   //register middleware
   app.use(bodyParser.json() , cors())
   app.listen(port, () =>  console.log(`server is up and running at ${port}`)

Pour vérifier si le serveur Express est opérationnel, exécutez le code suivant dans la fenêtre du terminal -

C:\Users\Admin\hello-world-server>node server.js

La sortie suivante s'affiche dans la console du serveur. Cela montre que le serveur express fonctionne sur le port 9000.

server is up and running at 9000

Si vous ouvrez le navigateur et tapez http://localhost:9000, vous obtiendrez l'écran suivant -

Pour arrêter le serveur, appuyez sur Ctrl + C.

Étape 2 - Installez GraphQL et Apollo Server

Maintenant qu'Express est configuré, l'étape suivante consiste à télécharger les dépendances GraphQL suivantes -

  • graphql
  • graphql-tools
  • apollo-server-express@1

Nous utiliserons le serveur Apollo v1.0 car il s'agit d'une version stable. Tapez les commandes suivantes pour installer ces dépendances -

C:\Users\Admin\hello-world-server>npm install graphql graphql-tools apollo-server-express@1

Nous pouvons vérifier si ces dépendances sont installées avec succès en vérifiant le package.json fichier que nous avons créé précédemment.

{
   "name": "hello-world-server",
   "private": true,
   
   "dependencies": {
      "apollo-server-express": "^1.4.0",
      "body-parser": "^1.18.3",
      "cors": "^2.8.4",
      "express": "^4.16.3",
      "graphql": "^0.13.2",
      "graphql-tools": "^3.1.1"
   }
}

Étape 3 - Définissez le schéma

Un schéma GraphQL définit le type d'objet qui peut être récupéré à partir d'un service et les champs dont il dispose. Le schéma peut être défini en utilisantGraphQL Schema Definition Language. Maintenant, ajoutez l'extrait de code suivant dans leserver.js fichier -

// Adding Type Definitions
const typeDefinition = `
   type Query  {
      greeting: String
   }

Ici, la requête contient un attribut de salutation qui renvoie une valeur de chaîne .

Étape 4 - Créer un résolveur

La première étape de la création d'un résolveur consiste à ajouter du code pour traiter la demande de champ de message d'accueil. Ceci est spécifié dans unresolver. La structure de la fonction de résolution doit correspondre au schéma. Ajoutez l'extrait de code suivant dans leserver.js fichier.

// Adding resolver
const  resolverObject = {
   Query : {
      greeting: () => 'Hello GraphQL  From TutorialsPoint !!'
   }
}

La deuxième étape consiste à lier le schéma et le résolveur en utilisant makeExecutableSchema. Cette fonction est prédéfinie dans le module graphql-tools. Ajoutez l'extrait de code suivant dans le server.js fichier.

const {makeExecutableSchema} = require('graphql-tools')
const schema = makeExecutableSchema({typeDefs:typeDefinition, resolvers:resolverObject})

Étape 5 - Définir des routes pour récupérer les données de l'application ReactJS / GraphiQL

Ajoutez l'extrait de code suivant dans le server.js fichier -

const {graphqlExpress, graphiqlExpress} = require('apollo-server-express')

   //create routes for graphql and graphiql
   app.use('/graphql',graphqlExpress({schema}))
   
   app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))

La fonction graphqlExpress permet d'enregistrer l'itinérairehttp://localhost:9000/graphql. L'application ReactJS peut utiliser ce point de terminaison pour interroger des données. De même, la fonction graphqliExpress permet d'enregistrer l'itinérairehttp://localhost:9000/graphiql. Cela sera utilisé par le client du navigateur GraphiQL pour tester l'API.

Le code server.js complet est comme indiqué ci-dessous -

const bodyParser = require('body-parser')
const cors = require('cors')
const express = require('express')
const port = process.env.PORT||9000
const app = express()

app.use(bodyParser.json() , cors())
const typeDefinition = `
type Query  {
   greeting: String
}`
const  resolverObject = {
   Query : {
      greeting: () => 'Hello GraphQL  From TutorialsPoint !!'
   }
}
const {makeExecutableSchema} = require('graphql-tools')

const schema = makeExecutableSchema({typeDefs:typeDefinition, resolvers:resolverObject})

const {graphqlExpress,graphiqlExpress} = require('apollo-server-express')

app.use('/graphql',graphqlExpress({schema}))
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))
app.listen(port, () =>  console.log(`server is up and running ${port}`))

Étape 6 - Démarrez l'application

Exécuter server.js en utilisant Node.js comme suit -

C:\Users\Admin\hello-world-server>node server.js

Étape 7 - Testez l'API GraphQL

Ouvrez le navigateur et saisissez http://localhost:9000/graphiql. Dans l'onglet de requête de GraphiQL, saisissez ce qui suit -

{
   greeting
}

La réponse du serveur est donnée ci-dessous -

{
   "data": {
      "greeting": "Hello GraphQL From TutorialsPoint !!"
   }
}

L'image suivante illustre la réponse -

Note - Veuillez vous assurer que Apollo Server version 1.0 est utilisé.

GraphQL est un langage fortement typé. Le système de types définit divers types de données pouvant être utilisés dans une application GraphQL. Le système de types aide à définir le schéma, qui est un contrat entre le client et le serveur. Les types de données GraphQL couramment utilisés sont les suivants:

Sr.No. Types et description
1

Scalar

Stocke une valeur unique

2

Object

Montre quel type d'objet peut être récupéré

3

Query

Type de point d'entrée vers d'autres types spécifiques

4

Mutation

Point d'entrée pour la manipulation des données

5

Enum

Utile dans une situation où vous avez besoin que l'utilisateur choisisse parmi une liste d'options prescrite

Type scalaire

Les types scalaires sont des types de données primitifs qui ne peuvent stocker qu'une seule valeur. Les types scalaires par défaut proposés par GraphQL sont -

  • Int - Entier 32 bits signé

  • Float - Valeur à virgule flottante double précision signée

  • String - UTF - séquence de 8 caractères

  • Boolean - Vrai ou faux

  • ID - Un identifiant unique, souvent utilisé comme identifiant unique pour récupérer un objet ou comme clé pour un cache.

La syntaxe pour définir un type scalaire est la suivante -

field: data_type

L'extrait de code ci-dessous définit un champ nommé salutation qui renvoie une valeur de chaîne.

greeting: String

Type d'objet

Le type d'objet est le type le plus couramment utilisé dans un schéma et représente un groupe de champs. Chaque champ à l'intérieur d'un type d'objet correspond à un autre type, permettant ainsi des types imbriqués. En d'autres termes, un type d'objet est composé de plusieurs types scalaires ou types d'objet.

La syntaxe pour définir un type d'objet est donnée ci-dessous -

type object_type_name
{
   field1: data_type
   field2:data_type 
   ....
   fieldn:data_type
}

Vous pouvez considérer l'extrait de code suivant -

--Define an object type--

type Student {
   stud_id:ID
   firstname: String
   age: Int
   score:Float
}

--Defining a GraphQL schema--  

type Query
{
   stud_details:[Student]
}

L'exemple donné ci-dessus définit un objet de type de données Student. Le champ stud_details dans le schéma de requête racine renverra une liste d'objets Student.

Type de requête

Une requête GraphQL est utilisée pour récupérer des données. C'est comme demander une ressource dans les API REST. Pour faire simple, le type de requête est la requête envoyée d'une application cliente au serveur GraphQL. GraphQL utilise leSchema Definition Language (SDL)pour définir une requête. Le type de requête est l'un des nombreux types de niveau racine dans GraphQL.

La syntaxe pour définir une requête est la suivante -

type Query {
   field1: data_type
   field2:data_type
   field2(param1:data_type,param2:data_type,...paramN:data_type):data_type
}

Un exemple de définition d'une requête -

type Query  {
   greeting: String
}

Type de mutation

Les mutations sont des opérations envoyées au serveur pour create, update ou deleteLes données. Ceux-ci sont analogues aux verbes PUT, POST, PATCH et DELETE pour appeler des API basées sur REST.

La mutation est l'un des types de données de niveau racine dans GraphQL. Le type Query définit les points d'entrée pour les opérations de récupération de données tandis que le type Mutation spécifie les points d'entrée pour les opérations de manipulation de données.

La syntaxe pour définir un type de mutation est donnée ci-dessous -

type Mutation {
   field1: data_type
   field2(param1:data_type,param2:data_type,...paramN:data_type):data_type 
}

Par exemple, nous pouvons définir un type de mutation pour ajouter un nouvel étudiant comme ci-dessous -

type Mutation {
   addStudent(firstName: String, lastName: String): Student
}

Type d'énumération

Un Enum est similaire à un type scalaire. Les énumérations sont utiles dans une situation où la valeur d'un champ doit provenir d'une liste d'options prescrite.

La syntaxe pour définir un type Enum est -

type enum_name{
   value1
   value2
}

L'extrait de code suivant illustre comment un type enum peut être défini -

type Days_of_Week{
   SUNDAY
   MONDAY
   TUESDAY
   WEDNESDAY
   THURSDAY
   FRIDAY
   SATURDAY
}

Type de liste

Les listes peuvent être utilisées pour représenter un tableau de valeurs d'un type spécifique. Les listes sont définies avec un modificateur de type [] qui encapsule les types d'objets, les scalaires et les énumérations.

La syntaxe suivante peut être utilisée pour définir un type de liste -

field:[data_type]

L'exemple ci-dessous définit un type de liste todos -

type Query {
   todos: [String]
}

Type non nul

Par défaut, chacun des types scalaires principaux peut être défini sur null. En d'autres termes, ces types peuvent soit renvoyer une valeur du type spécifié, soit ne pas avoir de valeur. Pour remplacer cette valeur par défaut et spécifier qu'un champ doit être défini, un point d'exclamation (!) Peut être ajouté à un type. Cela garantit la présence de valeur dans les résultats renvoyés par la requête.

La syntaxe suivante peut être utilisée pour définir un champ non nullable -

field:data_type!

Dans l'exemple ci-dessous, stud_id est déclaré comme un champ obligatoire.

type Student {
   stud_id:ID!
   firstName:String
   lastName:String
   fullName:String
   college:College
}

Un schéma GraphQL est au cœur de toute implémentation de serveur GraphQL. Il décrit les fonctionnalités disponibles pour les applications clientes qui s'y connectent. Nous pouvons utiliser n'importe quel langage de programmation pour créer un schéma GraphQL et construire une interface autour de lui.

Le runtime GraphQL définit un schéma générique basé sur un graphique pour publier les capacités du service de données qu'il représente. Les applications clientes peuvent interroger le schéma dans la limite de ses capacités. Cette approche dissocie les clients des serveurs et permet à la fois d'évoluer et d'évoluer indépendamment.

Dans ce chapitre, nous utilisons le serveur Apollo pour exécuter des requêtes GraphQL. lemakeExecutableSchema La fonction dans graphql-tools vous aide à lier le schéma et les résolveurs.

Syntaxe de la fonction makeExecutableSchema

le makeExecutableSchemaLa fonction prend un seul argument {} de type Object. La syntaxe d'utilisation de cette fonction est donnée ci-dessous -

import { makeExecutableSchema } from 'graphql-tools';

const jsSchema = makeExecutableSchema({
   typeDefs,
   resolvers, // optional
   logger, // optional
   allowUndefinedInResolve = false, // optional
   resolverValidationOptions = {}, // optional
   directiveResolvers = null, // optional
   schemaDirectives = null,  // optional
   parseOptions = {},  // optional
   inheritResolversFromInterfaces = false  // optional
});

Sr.No. Paramètre et description
1

typeDefs

C'est un argument requis. Il représente une requête GraphQL sous la forme d'une chaîne UTF-8.

2

Resolvers

C'est un argument optionnel (objet vide par défaut). Cela a des fonctions qui gèrent la requête.

3

logger

Cet argument est facultatif et peut être utilisé pour imprimer des erreurs sur la console du serveur.

4

parseOptions

Il s'agit d'un argument facultatif qui permet la personnalisation de l'analyse lors de la spécification de typeDefs sous forme de chaîne.

5

allowUndefinedInResolve

Ceci est vrai par défaut. Lorsqu'elle est définie sur false, vos fonctions de résolution lancent des erreurs si elles renvoient undefined.

6

resolverValidationOptions

Il s'agit d'un argument facultatif et accepte un objet avec des propriétés booléennes.

sept

inheritResolversFromInterfaces

Il s'agit d'un argument facultatif et accepte un argument booléen pour vérifier l'héritage des objets des résolveurs.

Illustration

Créons une application simple pour comprendre ce schéma. Cela créera un schéma pour interroger la liste des étudiants à partir du serveur. Les données des élèves seront stockées dans un fichier plat et nous utiliserons un module de nœud appelénotarealdb pour simuler une base de données et lire à partir du fichier plat.

Étape 1 - Téléchargez et installez les dépendances requises pour le projet

Créez un dossier nommé schema-app. Changez votre répertoire en schema-app depuis le terminal. Suivez ensuite les étapes 3 à 5 expliquées dans le chapitre Configuration de l'environnement pour terminer le téléchargement et l'installation.

Étape 2 - Créer un schéma

Ajouter schema.graphql fichier dans le dossier du projet, schema-app et ajoutez le code suivant -

type Query {
   greeting:String
   students:[Student]
}

type Student {
   id:ID!
   firstName:String
   lastName:String
   password:String
   collegeId:String
}

La racine du schéma sera le type de requête. La requête comporte deux champs - salutation et étudiants qui renvoie respectivement une chaîne et une liste d'étudiants. L'élève est déclaré comme un type d'objet car il contient plusieurs champs. Le champ ID est déclaré non nul.

Étape 3 - Créer un résolveur

Créer un fichier resolvers.js dans le dossier du projet et ajoutez le code suivant -

const db = require('./db')
const Query = {
   greeting:() => {
      return "hello from  TutorialsPoint !!!"
   },
   students:() => db.students.list()
}

module.exports = {Query}

Ici, le message d'accueil et les étudiants sont les résolveurs qui gèrent la requête. students resolver functionrenvoie une liste d'étudiants de la couche d'accès aux données. Pour accéder aux fonctions du résolveur en dehors du module, l'objet Requête doit être exporté en utilisantmodule.exports.

Étape 4 - Exécutez l'application

Créez un fichier server.js et reportez-vous à l'étape 8 du chapitre Configuration de l'environnement. L'étape suivante consiste à exécuter la commande npm start dans le terminal. Le serveur sera opérationnel sur le port 9000. Ici, nous utilisons GraphiQL comme client pour tester l'application. Ouvrez le navigateur et saisissez l'URL,http://localhost:9000/graphiql.

Tapez la requête suivante dans l'éditeur -

{
   greeting
   students {
      id
      firstName
      lastName
   }
}

La requête affichera la sortie comme indiqué ci-dessous -

Note- Nous pouvons remplacer le student.json par un appel API RESTful pour récupérer les données des étudiants ou même une vraie base de données comme MySQL ou MongoDB. GraphQL devient une enveloppe fine autour de votre couche d'application d'origine pour améliorer les performances.

Resolver est une collection de fonctions qui génèrent une réponse pour une requête GraphQL. En termes simples, un résolveur agit comme un gestionnaire de requêtes GraphQL. Chaque fonction de résolution dans un schéma GraphQL accepte quatre arguments de position comme indiqué ci-dessous -

fieldName:(root, args, context, info) => { result }

Un exemple de fonctions de résolveur est illustré ci-dessous -

//resolver function  with no parameters and returning string
greeting:() => {
   return "hello from  TutorialsPoint !!!"
}

//resolver function with no parameters and returning list
students:() => db.students.list()

//resolver function with arguments and returning object
studentById:(root,args,context,info) => {
   return db.students.get(args.id);
}

Vous trouverez ci-dessous les arguments de position et leur description -

Sr.No. Arguments et description
1

root

Objet qui contient le résultat renvoyé par le résolveur sur le champ parent.

2

args

Un objet avec les arguments passés dans le champ de la requête.

3

context

Il s'agit d'un objet partagé par tous les résolveurs dans une requête particulière.

4

info

Il contient des informations sur l'état d'exécution de la requête, y compris le nom du champ, le chemin d'accès au champ à partir de la racine.

Format de résultat du résolveur

Les résolveurs dans GraphQL peuvent renvoyer différents types de valeurs comme indiqué ci-dessous -

Sr.No. Arguments et description
1

null or undefined

cela indique que l'objet n'a pas pu être trouvé

2

array

ceci n'est valable que si le schéma indique que le résultat d'un champ doit être une liste

3

promise

les résolveurs effectuent souvent des actions asynchrones telles que la récupération à partir d'une base de données ou d'une API backend, afin de pouvoir renvoyer des promesses

4

scalar or object

un résolveur peut également renvoyer d'autres valeurs

Illustration

Créons une application simple pour comprendre le résolveur. Cela créera un schéma pour interroger un étudiant par identifiant à partir du serveur. Les données des élèves seront stockées dans un fichier plat et nous utiliserons un module de nœud appelénotarealdb pour simuler une base de données et lire à partir d'un fichier plat.

Ce qui suit est un processus par étapes pour créer une application simple -

Étape 1 - Téléchargez et installez les dépendances requises pour le projet

Créez un dossier nommé resolver-app. Changez votre répertoire enresolver-appdepuis le terminal. Plus tard, suivez les étapes 3 à 5 du chapitre Configuration de l'environnement.

Étape 2 - Créer un schéma

Ajoutez le fichier schema.graphql dans le dossier du projet resolver-app et ajoutez le code suivant -

type Query { 
   greeting:String
   students:[Student]
   studentById(id:ID!):Student 
}

type Student {
   id:ID!
   firstName:String
   lastName:String
   password:String
   collegeId:String
}

Le fichier de schéma montre que l'utilisateur peut demander le message d' accueil, les étudiants et studentById . Pour récupérer des étudiants avec un identifiant spécifique, nous utilisonsdata type ID!qui montre un champ d'identifiant unique non nullable. Le champ des étudiants renvoie un tableau d'étudiants et le message d'accueil renvoie une valeur de chaîne simple.

Étape 3 - Créer un résolveur

Créer un fichier resolvers.js dans le dossier du projet et ajoutez le code suivant -

const db = require('./db')
const Query = {
   //resolver function for greeting
   greeting:() => {
      return "hello from  TutorialsPoint !!!"
   },
   
   //resolver function for students returns list
   students:() => db.students.list(),

   //resolver function for studentbyId
   studentById:(root,args,context,info) => {
      //args will contain parameter passed in query
      return db.students.get(args.id);
   }
}
module.exports = {Query}

Ici, studentById prend trois paramètres. Comme discuté dans ce chapitre, le studentId peut être récupéré à partir d'arguments; root contiendra l'objet Query lui-même. Pour renvoyer un étudiant spécifique, nous devons appeler la méthode get avec le paramètre id dans la collection des étudiants.

Ici, salutation, étudiants, studentById sont les résolveurs qui gèrent la requête.students resolver functionrenvoie une liste d'étudiants de la couche d'accès aux données. Pour accéder aux fonctions de résolution en dehors du module, l'objet Requête doit être exporté à l'aide de module.exports.

Étape 4 - Exécutez l'application

Créez un fichier server.js. Reportez-vous à l'étape 8 du chapitre Configuration de l'environnement. Exécutez la commande npm start dans le terminal. Le serveur sera opérationnel sur le port 9000. Ici, nous utilisons GraphiQL comme client pour tester l'application.

Ouvrez le navigateur et entrez l'url, http://localhost:9000/graphiql. Tapez la requête suivante dans l'éditeur -

{  
   studentById(id:"S1001") {
      id
      firstName
      lastName
   }
}

Le résultat de la requête ci-dessus est comme indiqué ci-dessous -

{
   "data": {
      "studentById": {
         "id": "S1001",
         "firstName": "Mohtashim",
         "lastName": "Mohammad"
      }
   }
}

Une opération GraphQL peut être une opération de lecture ou d'écriture. Une requête GraphQL est utilisée pour lire ou récupérer des valeurs tandis qu'une mutation est utilisée pour écrire ou publier des valeurs. Dans les deux cas, l'opération est une simple chaîne qu'un serveur GraphQL peut analyser et répondre avec des données dans un format spécifique. Le format de réponse populaire généralement utilisé pour les applications mobiles et Web est JSON.

La syntaxe pour définir une requête est la suivante -

//syntax 1
query query_name{ someField }

//syntax 2
{ someField }

Voici un exemple de requête -

//query with name myQuery
query myQuery{
   greeting
}

// query without any name
{
   greeting
}

Il ressort clairement de l'exemple ci-dessus que le mot-clé de requête est facultatif.

Les requêtes GraphQL aident à réduire la surextraction de données. Contrairement à une API Restful, GraphQL permet à un utilisateur de restreindre les champs qui doivent être récupérés sur le serveur. Cela signifie des requêtes plus petites et moins de trafic sur le réseau; ce qui réduit à son tour le temps de réponse.

Illustration 1 - Modèle d'étudiant de requête avec un champ personnalisé

Dans cet exemple, nous avons un ensemble d'étudiants stockés dans un fichier json. Chaque modèle étudiant a des champs comme firstName, lastName et id mais pas de fullName. Ici, nous verrons comment créer une requête pour récupérer le nom complet de tous les étudiants. Pour cela, nous devons créer un champ fullName dans les deux résolveur de schéma.

Voyons comment faire cette illustration en utilisant les étapes ci-dessous -

Étape 1 - Téléchargez et installez les dépendances requises pour le projet

Créez un dossier nommé query-app. Changez votre répertoire enquery-appdepuis le terminal. Plus tard, suivez les étapes 3 à 5 expliquées dans le chapitre Configuration de l'environnement.

Étape 2 - Créer un schéma

Ajouter schema.graphql fichier dans le dossier de projet query-app et ajoutez le code suivant -

type Query {
   greeting:String
   students:[Student]
   studentById(id:ID!):Student
}

type Student {
   id:ID!
   firstName:String
   lastName:String
   fullName:String 
}

Notez qu'il n'y a pas de champ fullName dans lestudents.jsonfichier. Cependant, nous devons récupérer le nom complet de l'étudiant via une requête. Le fullName , dans ce cas, sera un champ personnalisé qui n'est pas disponible avec la source de données.

Étape 3 - Créer un résolveur

Créer un fichier resolvers.js dans le dossier du projet et ajoutez le code suivant -

const db = require('./db')
const Query = {
   //resolver function for greeting
   greeting:() => {
      return "hello from  TutorialsPoint !!!"
   },
   
   //resolver function for students returns list
   students:() => db.students.list(),

   //resolver function for studentbyId
   studentById:(root,args,context,info) => {
      //args will contain parameter passed in query
      return db.students.get(args.id);
   }
}

//for each single student object returned,resolver is invoked

const Student = {
   fullName:(root,args,context,info) => {
      return root.firstName+":"+root.lastName
   }
}

module.exports = {Query,Student}

Étape 4 - Exécutez l'application

Créer un server.jsfichier. Reportez-vous à l'étape 8 du chapitre Configuration de l'environnement. Exécutez la commande  npm start dans le terminal. Le serveur sera opérationnel sur le port 9000. Ici, nous utilisons GraphiQL comme client pour tester l'application.

Ouvrez le navigateur et saisissez l'URL http://localhost:9000/graphiql. Tapez la requête suivante dans l'éditeur -

{
   students{
      id
      fullName
   }
}

La réponse à la requête est donnée ci-dessous -

{
   "data": {
      "students": [
         {
            "id": "S1001",
            "fullName": "Mohtashim:Mohammad"
         },
         
         {
            "id": "S1002",
            "fullName": "Kannan:Sudhakaran"
         },
         
         {
            "id": "S1003",
            "fullName": "Kiran:Panigrahi"
         }
      ]
   }
}

Créer un server.js et ajoutez le code suivant -

const bodyParser = require('body-parser');
const cors = require('cors');
const express = require('express');

const db = require('./db');
const port = 9000;
const app = express();

//loading type definitions from schema file
const fs = require('fs')
const typeDefs = fs.readFileSync('./schema.graphql',{encoding:'utf-8'})

//loading resolvers
const resolvers = require('./resolvers')

//binding schema and resolver
const {makeExecutableSchema} = require('graphql-tools')
const schema = makeExecutableSchema({typeDefs, resolvers})

//enabling cross domain calls and form post
app.use(cors(), bodyParser.json());

//enabling routes
const  {graphiqlExpress,graphqlExpress} = require('apollo-server-express')
app.use('/graphql',graphqlExpress({schema}))
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))

//registering port
app.listen(port, () => console.info(`Server started on port ${port}`));

Exécutez la commande npm start dans le terminal. Le serveur sera opérationnel sur le port 9000. Ici, nous utilisons GraphiQL comme client pour tester l'application.

Ouvrez le navigateur et saisissez l'URL http://localhost:9000/graphiql. Tapez la requête suivante dans l'éditeur -

{
   students{
      id
      fullName
   }
}

La réponse à la requête est donnée ci-dessous -

{
   "data": {
      "students": [
         {
            "id": "S1001",
            "fullName": "Mohtashim:Mohammad"
         },
         {
            "id": "S1002",
            "fullName": "Kannan:Sudhakaran"
         },
         {
            "id": "S1003",
            "fullName": "Kiran:Panigrahi"
         }
      ]
   }
}

Illustration 2 - Requête imbriquée

Créons une requête imbriquée pour récupérer les détails de l'étudiant et les détails de son collège. Nous travaillerons avec le même dossier de projet.

Étape 1 - Modifier le schéma

Le fichier de schéma contient déjà le champ étudiant . Ajoutons un collège de terrain et définissons son type.

type College {
   id:ID!
   name:String
   location:String
   rating:Float
}

type Student {
   id:ID!
   firstName:String
   lastName:String
   fullName:String
   college:College
}

Étape 2 - Modifiez le resolver.js

Nous devons ajouter une fonction de résolution d'université comme ci-dessous. La fonction de résolution du collège sera exécutée pour chaque objet étudiant renvoyé. Le paramètre racine du résolveur dans ce cas contiendra student .

const Student = {
   fullName:(root,args,context,info) => {
      return root.firstName+":"+root.lastName
   },
   college:(root) => {
      return db.colleges.get(root.collegeId);
   }
}
module.exports = {Query,Student}

Le résolveur renvoie le collège de chaque étudiant en appelant la méthode get de la collecte du collège et en passant le collegeId . Nous avons une relation d'association entre l'étudiant et le collège par le biais de collegeId .

Étape 3 - Testez l'application

Ouvrez la fenêtre du terminal et accédez au dossier du projet. Tapez la commande -npm start. Lancez le navigateur et entrez l'URLhttp://localhost:9000/graphiql.

Entrez la requête suivante dans la fenêtre GraphiQL -

{
   students{
      id
      firstName
      college {
         id
         name
         location
         rating
      }
   }
}

La réponse à la requête est la suivante -

{
   "data": {
      "students": [
         {
            "id": "S1001",
            "firstName": "Mohtashim",
            "college": {
               "id": "col-102",
               "name": "CUSAT",
               "location": "Kerala",
               "rating": 4.5
            }
         },
         
         {
            "id": "S1002",
            "firstName": "Kannan",
            "college": {
               "id": "col-101",
               "name": "AMU",
               "location": "Uttar Pradesh",
               "rating": 5
            }
         },
         
         {
            "id": "S1003",
            "firstName": "Kiran",
            "college": {
               "id": "col-101",
               "name": "AMU",
               "location": "Uttar Pradesh",
               "rating": 5
            }
         }
      ]
   }
}

Qu'est-ce qu'une variable de requête?

Si une requête a des valeurs dynamiques à transmettre, représentez ces valeurs dynamiques à l'aide de variables. Par conséquent, la requête peut être réutilisée par les applications clientes.

Illustration

Créons une application simple pour comprendre la variable de requête.

Étape 1 - Modifier le fichier de schéma

Ajoutez un champ sayHello qui prend un paramètre de chaîne et renvoie une chaîne. Les valeurs de nom seront dynamiques dans l'application cliente.

type Query {
   sayHello(name:String!):String
}

Étape 2 - Modifier le fichier resolver.js

Ajoutez un résolveur sayHello qui prend le paramètre comme ci-dessous -

sayHello:(root,args,context,info) => `Hi ${args.name} GraphQL server says Hello to you!!`

Étape 3 - Déclarer la variable de requête dans GraphiQL

Une variable est déclarée avec $ suivi du nom de la variable. Par exemple: $ myname_Variable.

Une fois que $ myname_Variable est déclaré, il doit être utilisé avec une syntaxe de requête nommée. La requête, myQuery prend une valeur de chaîne et la transmet à sayHello comme indiqué ci-dessous -

query myQuery($myname_Variable:String!) { sayHello(name:$myname_Variable)
}

Définissez la valeur de $ myname_Variable en tant qu'objet JSON dans la section Variables de requête du client GraphiQL.

{
   "myname_Variable": "Mohtashim"
}

La sortie du code ci-dessus est la suivante -

{
   "data": {
      "sayHello": "Hi Mohtashim GraphQL server says Hello to you!!"
   }
}

Comment utiliser la variable de requête avec Enum

Voyons comment utiliser une variable de requête lorsque le paramètre de champ est enum type.

Étape 1 - Modifier le fichier schema.graphql

enum ColorType {
   RED
   BLUE
   GREEN
}

type Query {
   setFavouriteColor(color:ColorType):String
}

La fonction setFavouriteColor prend enum comme entrée et renvoie une valeur de chaîne.

Étape 2 - Modifier le fichier resolvers.js

La fonction de résolution setFavouriteColor prend racine et args . La valeur enum transmise à la fonction lors de l'exécution est accessible via le paramètre args.

setFavouriteColor:(root,args) => {
   return  "Your Fav Color is :"+args.color;
}

Étape 3 - Déclarer une variable de requête dans GraphiQL

La requête est nommée query_to_setColorqui prend une variable du nom color_variable de ColorType. Cette variable est transmise à la méthode setFavouriteColor.

query query_to_setColor($color_variable:ColorType) {
   setFavouriteColor(color:$color_variable)
}

Dans la section de variable de requête de GraphiQL, tapez le code suivant -

{
   "color_variable":"RED"
}

La réponse est indiquée ci-dessous -

{
   "data": {
      "setFavouriteColor": "Your Fav Color is: RED"
   }
}

Dans ce chapitre, nous allons apprendre les requêtes de mutation dans GraphQL.

Les requêtes de mutation modifient les données dans le magasin de données et renvoient une valeur. Il peut être utilisé pour insérer, mettre à jour ou supprimer des données. Les mutations sont définies comme faisant partie du schéma.

La syntaxe d'une requête de mutation est donnée ci-dessous -

mutation{
   someEditOperation(dataField:"valueOfField"):returnType
}

Illustration

Voyons comment ajouter un nouvel enregistrement étudiant dans la banque de données à l'aide d'une requête de mutation.

Étape 1 - Téléchargez et installez les dépendances requises pour le projet

Créez un dossier de projet sous le nom mutation-app. Changez votre répertoire en mutation-app depuis le terminal. Suivez les étapes 3 à 5 expliquées dans le chapitre Configuration de l'environnement.

Étape 2 - Créez un fichier schema.graphql

Ajouter schema.graphql fichier dans le dossier du projet mutation-app et ajoutez le code suivant -

type Query {
   greeting:String
}

type Mutation {
   createStudent(collegeId:ID,firstName:String,lastName:String):String
}

Notez que la fonction createStudent renvoie un type String. Il s'agit d'un identifiant unique (ID) qui est généré après la création d'un étudiant.

Étape 3 - Créez un fichier resolver.js

Créez un fichier resolvers.js dans le dossier du projet et ajoutez le code suivant -

const db = require('./db')
const Mutation = {
   createStudent:(root,args,context,info) => {
      return db.students.create({collegeId:args.collegeId,
      firstName:args.firstName,
      lastName:args.lastName})
   }
}
const Query = {
   greeting:() => "hello"
}

module.exports = {Query,Mutation}

La fonction de mutation pointe vers la collection des étudiants dans le magasin de données. Pour ajouter un nouvel étudiant , appelez la méthode create dans la collection des étudiants. L' objet args contiendra les paramètres qui sont passés dans la requête. La méthode create de la collection des étudiants renverra l'ID d'un objet étudiant nouvellement créé.

Étape 4 - Exécutez l'application

Créer un server.jsfichier. Reportez-vous à l'étape 8 du chapitre Configuration de l'environnement. Exécutez la commande npm start dans le terminal. Le serveur sera opérationnel sur le port 9000. Ici, nous utilisons GraphiQL comme client pour tester l'application.

L'étape suivante consiste à ouvrir le navigateur et à saisir l'URL http://localhost:9000/graphiql. Tapez la requête suivante dans l'éditeur -

//college Id should be matched with data from colleges.json for easy retrieval

mutation {
   createStudent(collegeId:"col-2",firstName:"Tim",lastName:"George")
}

La requête ci-dessus créera un objet étudiant dans le fichier student.json. La requête renverra un identifiant unique. La réponse de la requête est comme indiqué ci-dessous -

{
   "data": {
      "createStudent": "SkQtxYBUm"
   }
}

Pour vérifier si l'objet étudiant est créé, nous pouvons utiliser la requête studentById. Vous pouvez également ouvrir le fichier student.json à partir du dossier de données pour vérifier l'ID.

Pour utiliser la requête studentById, modifiez le schema.graphql comme indiqué ci-dessous -

type Query {
   studentById(id:ID!):Student
}

type Student {
   id:ID!
   firstName:String
   lastName:String
   collegeId:String
}

Modifier le resolver.js fichier comme indiqué ci-dessous -

const db = require('./db')
const Query = {
   studentById:(root,args,context,info) => {
      return db.students.get(args.id);
   }
}

const Mutation = {
   createStudent:(root,args,context,info) => {
      return db.students.create({collegeId:args.collegeId,
      firstName:args.firstName,
      lastName:args.lastName})
   }
}

module.exports = {Query,Mutation}

Ci-dessous, la requête pour obtenir un étudiant par identifiant unique renvoyé par la requête de mutation -

{
    studentById(id:"SkQtxYBUm") {
    id
    firstName
    lastName
  }
}

La réponse du serveur est la suivante -

{
   "data": {
      "studentById": {
         "id": "SkQtxYBUm",
         "firstName": "Tim",
         "lastName":"George"
      }
   }
}

Renvoyer un objet en mutation

Il est recommandé de renvoyer un objet en mutation. Par exemple, l'application cliente souhaite récupérer les détails des étudiants et des collèges. Dans ce cas, plutôt que de faire deux requêtes différentes, nous pouvons créer une requête qui renvoie un objet contenant les étudiants et leurs détails de collège.

Étape 1 - Modifier le fichier de schéma

Ajouter une nouvelle méthode nommée addStudent qui renvoie un objet de type mutation schema.graphql.

Apprenons à accéder aux détails du collège via les détails des étudiants. Ajoutez le type d'université dans le fichier de schéma.

type Mutation {
   addStudent_returns_object(collegeId:ID,firstName:String,lastName:String):Student

   createStudent(collegeId:ID,firstName:String,lastName:String):String
}

type College {
   id:ID!
   name:String
   location:String
   rating:Float
}

type Student {
   id:ID!
   firstName:String
   lastName:String
   college:College
}

Étape 2 - Mettez à jour le fichier resolvers.js

Mettre à jour un fichier resolvers.js dans le dossier du projet et ajoutez le code suivant -

const Mutation = {
   createStudent:(root,args,context,info) => {

      return db.students.create({
         collegeId:args.collegeId,
         firstName:args.firstName,
         lastName:args.lastName
      })
   },
   
   // new resolver function
   addStudent_returns_object:(root,args,context,info) => {
      const id = db.students.create({
         collegeId:args.collegeId,
         firstName:args.firstName,
         lastName:args.lastName
      })

      return db.students.get(id)
   }
}

//for each single student object returned,resolver is invoked
const Student = {
   college:(root) => {
      return db.colleges.get(root.collegeId);
   }
}

module.exports = {Query,Student,Mutation}

Étape 3 - Démarrez le serveur et tapez la requête de requête dans GraphiQL

Ensuite, nous allons démarrer le serveur et demander la requête dans GraphiQL avec le code suivant -

mutation {
   addStudent_returns_object(collegeId:"col-101",firstName:"Susan",lastName:"George") {
      id
      firstName
      college{
         id
         name
      }
   }
}

La requête ci-dessus ajoute un nouvel étudiant et récupère l'objet étudiant avec l'objet college. Cela évite les allers-retours vers le serveur.

La réponse est comme donnée ci-dessous -

{
   "data": {
      "addStudent_returns_object": {
         "id": "rklUl08IX",
         "firstName": "Susan",
         "college": {
            "id": "col-101",
            "name": "AMU"
         }
      }
   }
}

Lors de l'ajout ou de la modification de données, il est important de valider l'entrée utilisateur. Par exemple, nous pouvons avoir besoin de nous assurer que la valeur d'un champ n'est toujours pas nulle. On peut utiliser! (non-nullable) tapez marker dans GraphQL pour effectuer une telle validation.

La syntaxe d'utilisation de ! le marqueur de type est comme indiqué ci-dessous -

type TypeName {
   field1:String!,
   field2:String!,
   field3:Int!
}

La syntaxe ci-dessus garantit que tous les champs ne sont pas nuls.

Si nous voulons implémenter des règles supplémentaires comme vérifier la longueur d'une chaîne ou vérifier si un nombre se trouve dans une plage donnée, nous pouvons définir des validateurs personnalisés. La logique de validation personnalisée fera partie de la fonction de résolution. Comprenons cela à l'aide d'un exemple.

Illustration - Implémentation de validateurs personnalisés

Créons un formulaire d'inscription avec une validation de base. Le formulaire comportera des champs email, prénom et mot de passe.

Étape 1 - Téléchargez et installez les dépendances requises pour le projet

Créez un dossier nommé validation-app. Changez le répertoire en validation-app depuis le terminal. Suivez les étapes 3 à 5 expliquées dans le chapitre Configuration de l'environnement.

Étape 2 - Créer un schéma

Ajouter schema.graphql fichier dans le dossier du projet validation-app et ajoutez le code suivant -

type Query {
   greeting:String
}

type Mutation {
   signUp(input:SignUpInput):String
}

input SignUpInput {
   email:String!,
   password:String!,
   firstName:String!
}

Note- Nous pouvons utiliser le type d'entrée SignUpInput pour réduire le nombre de paramètres dans la fonction signUp. Ainsi, la fonction signUp ne prend qu'un seul paramètre de type SignUpInput.

Étape 3 - Créer des résolveurs

Créer un fichier resolvers.js dans le dossier du projet et ajoutez le code suivant -

const Query = {
   greeting:() => "Hello"
}

const Mutation ={
   signUp:(root,args,context,info) => {

      const {email,firstName,password} = args.input;

      const emailExpression = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
      
      const isValidEmail =  emailExpression.test(String(email).toLowerCase())
      if(!isValidEmail)
      throw new Error("email not in proper format")

      if(firstName.length > 15)
      throw new Error("firstName should be less than 15 characters")

      if(password.length < 8 )
      throw new Error("password should be minimum 8 characters")
      
      return "success";
   }
}
module.exports = {Query,Mutation}

La fonction résolveur, signUp accepte les paramètres email, mot de passe et prénom. Celles-ci seront transmises via la variable d'entrée afin de pouvoir y accéder via args.input.

Étape 4 - Exécutez l'application

Créez un fichier server.js. Reportez-vous à l'étape 8 du chapitre Configuration de l'environnement. Exécutez la commande npm start dans le terminal. Le serveur sera opérationnel sur le port 9000. Ici, nous utiliserons GraphiQL comme client pour tester l'application.

Ouvrez le navigateur et entrez l'URL http://localhost:9000/graphiql. Tapez la requête suivante dans l'éditeur -

mutation doSignUp($input:SignUpInput) { signUp(input:$input)
}

Étant donné que l'entrée pour la fonction d'inscription est un type complexe, nous devons utiliser des variables de requête dans graphiql. Pour cela, nous devons d'abord donner un nom à la requête et l'appeler doSignUp, l'entrée $ est une variable de requête.

La variable de requête suivante doit être saisie dans l'onglet Variables de requête de graphiql -

{
   "input":{
      "email": "abc@abc",
      "firstName": "kannan",
      "password": "pass@1234"
   }
}

Le tableau des erreurs contient les détails des erreurs de validation comme indiqué ci-dessous -

{
   "data": {
      "signUp": null
   },
   
   "errors": [
      {
         "message": "email not in proper format",
         "locations": [
            {
               "line": 2,
               "column": 4
            }
         ],
         "path": [
            "signUp"
         ]
      }
   ]
}

Nous devons entrer une entrée appropriée pour chaque champ comme indiqué ci-dessous -

{
   "input":{
      "email": "[email protected]",
      "firstName": "kannan",
      "password": "pass@1234"
   }
}

La réponse est la suivante -

{
   "data": {
      "signUp": "success"
   }
}

Ici, dans la requête ci-dessous, nous n'attribuons aucun mot de passe.

{
   "input":{
      "email": "[email protected]",
      "firstName": "kannan"
   }
}

Si un champ obligatoire n'est pas fourni, le serveur qraphql affichera l'erreur suivante -

{
   "errors": [
      {
         "message": "Variable \"$input\" got invalid value {\"email\":\"[email protected]\",\"firstName\":\"kannan\"}; Field value.password of required type String! was not provided.",
         "locations": [
            {
               "line": 1,
               "column": 19
            }
         ]
      }
   ]
}

Les applications Web envoient et récupèrent des données de manière asynchrone (en arrière-plan). AJAX permet aux sites Web de charger du contenu sur l'écran sans actualiser la page. jQuery fournit plusieurs méthodes pour la fonctionnalité AJAX, facilitant ainsi l'utilisation d'AJAX. Dans ce chapitre, nous allons apprendre comment intégrer GraphQL avec jQuery.

Considérez une application utilisant une architecture client-serveur. Nous pouvons créer une page Web frontale qui demande des données à un serveur GraphQL. La page Web effectuera des appels AJAX en utilisant jQuery vers le serveur GraphQL.

Pour intégrer GraphQL à JQuery, inspectons les en-têtes de requête GraphiQL et comprenons les paramètres de la requête.

Commencer le hello-worldapp (reportez-vous au chapitre 6 pour l'illustration correspondante). Tapez la requête graphql {salutation} dans la fenêtre GraphiQL. Faites un clic droit et inspectez ou appuyez sur (ctrl + shift + I) sur chrome pour accéder à l'onglet réseau comme indiqué ci-dessous -

Du simple hello-world exemple, nous pouvons comprendre que http method utilisé est POST. Maintenant, dans le navigateur, faites défiler jusqu'à la section d'en-tête pour afficher la charge utile de la  demande .

Une fois que vous cliquez sur view code, vous verrez ce qui suit dans la section request payload de chrome.

{"query":"{\n  greeting\n}","variables":null,"operationName":null}

Notez également l'URL de la requête, http://localhost:9000/graphql qui doit être appelé depuis l'application cliente.

Illustration

Comprenons comment intégrer GraphQL à JQuery en utilisant un processus par étapes.

Configuration du serveur

Nous allons apprendre à configurer le serveur en suivant les étapes suivantes -

Étape 1 - Téléchargez et installez les dépendances requises pour le projet

Créez un dossier nommé jquery-server-app. Changez votre répertoire en jquery-server-app depuis le terminal. Suivez les étapes 3 à 5 expliquées dans le chapitre Configuration de l'environnement.

Étape 2 - Créer un schéma

Ajouter le fichier schema.graphql dans le dossier du projet jquery-server-app et ajoutez le code suivant -

type Query
{
   greeting: String
   sayHello(name:String!):String
}

Le fichier a défini deux requêtes greeting et sayHello. La requête sayHello accepte un paramètre de chaîne et renvoie une autre chaîne. Le paramètre de la fonction sayHello () n'est pas nul.

Étape 3 - Créer des résolveurs

Créez un fichier resolvers.js dans le dossier du projet et ajoutez le code suivant -

const Query =
{
   greeting: () => 'Hello GraphQL  From TutorialsPoint !!' ,
   sayHello:(root,args,context,info) =>  `Hi ${args.name} GraphQL server says Hello to you!!`
}
module.exports = {Query}

Ici, greeting et sayHellosont deux résolveurs. Dans le résolveur sayHello, la valeur passée au paramètre name est accessible via args. Pour accéder aux fonctions du résolveur en dehors du module, l'objet Requête doit être exporté en utilisantmodule.exports.

Étape 4 - Exécutez l'application

Créez un fichier server.js. Reportez-vous à l'étape 8 du chapitre Configuration de l'environnement. Exécutez la commande npm start dans le terminal. Le serveur sera opérationnel sur le port 9000. Ici, nous utilisons GraphiQL comme client pour tester l'application.

Ouvrez le navigateur et saisissez l'URL http://localhost:9000/graphiql. Tapez la requête suivante dans l'éditeur -

{
   greeting,
   sayHello(name:"Mohtashim")
}

La réponse du serveur est la suivante -

{
   "data": {
      "greeting": "Hello GraphQL From TutorialsPoint !!",
      "sayHello": "Hi Mohtashim GraphQL server says Hello to you!!"
   }
}

Configuration du client

Depuis, nous avons déjà configuré le serveur, nous allons maintenant apprendre à configurer le client.

Étape 1 - Créez un nouveau dossier jquery-client-app en dehors du dossier du projet actuel

Tout d'abord, nous allons créer un dossier nommé jquery-client-app en dehors du dossier du projet.

Étape 2 - Créez une page HTML index.html pour l'intégration jQuery

Nous allons créer une application client dans jquery et invoquer les deux méthodes. Voici le code pour index.html fichier. le index.html page envoie des requêtes au serveur lorsque les boutons - Greet et SayHellosont cliqués. Nous ferons une requête asynchrone en utilisant la fonction $ .ajax ().

<!DOCTYPE html>
<html>
   <head>
      <script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      <script>
         $(document).ready(function() { $("#btnSayhello").click(function() {

               const name = $("#txtName").val(); console.log(name); $("#SayhelloDiv").html('loading....');

               $.ajax({url: "http://localhost:9000/graphql", contentType: "application/json",type:'POST', data: JSON.stringify({ query:`{ sayHello(name:"${name}")}`
                  }),
                  success: function(result) {
                     console.log(JSON.stringify(result))
                     $("#SayhelloDiv").html("<h1>"+result.data.sayHello +"</h1>"); } }); }); $("#btnGreet").click(function() {
               $("#greetingDiv").html('loading....'); //https://kannan-first-graphql-app.herokuapp.com/graphql $.ajax({url: "http://localhost:9000/graphql",
                  contentType: "application/json",
                  type:'POST',
                  data: JSON.stringify({
                     query:`{greeting}`
                  }),
                  success: function(result) {
                     $("#greetingDiv").html("<h1>"+result.data.greeting+"</h1>");
                  }
               });
            });
         });
      </script>
   </head>
   
   <body>
      <h1>Jquery Client </h1>

      <hr/>
      <section>
         <button id = "btnGreet">Greet</button>
         <br/> <br/>
         <div id = "greetingDiv"> </div>
      </section>
      
      <br/> <br/> <br/>
      <hr/>

      <section>
         Enter a name:<input id = "txtName" type = "text" value = "kannan"/>
         <button id = "btnSayhello">SayHello</button>
         <div id = "SayhelloDiv"> </div>
      </section>
   </body>
</html>

Ouvrez ce fichier dans le navigateur et cliquez sur le bouton pour voir la réponse. La sortie sera comme indiqué ci-dessous -

React est une bibliothèque Javascript pour la création d'interfaces utilisateur. Ce chapitre explique comment intégrer GraphQL à une application React.

Illustration

Le moyen le plus rapide de configurer un projet de réaction consiste à utiliser l'   outil Créer une application React . Dans les sections suivantes, nous apprendrons comment configurer à la fois le serveur et le client.

Configuration du serveur

Pour configurer le serveur, suivez les étapes ci-dessous -

Étape 1 - Téléchargez et installez les dépendances requises pour le projet

Créer un dossier react-server-app. Changez votre répertoire en react-server-app depuis le terminal. Suivez les étapes 3 à 5 expliquées dans le chapitre Configuration de l'environnement.

Étape 2 - Créer un schéma

Ajouter schema.graphql fichier dans le dossier du projet react-server-app et ajoutez le code suivant -

type Query
{
   greeting: String
   sayHello(name:String!):String
}

Le fichier a défini deux requêtes - salutation et sayHello. La requête sayHello accepte un paramètre de chaîne et renvoie une autre chaîne. Le paramètre de la fonction sayHello () n'est pas nul.

Étape 3 - Créer des résolveurs

Créer un fichier resolvers.js dans le dossier du projet et ajoutez le code suivant -

const Query =
{
   greeting: () => 'Hello GraphQL  From TutorialsPoint !!' ,
   sayHello:(root,args,context,info) =>  `Hi ${args.name} GraphQL server says Hello to you!!`
}
module.exports = {Query}

Ici, salutation et salutation sont deux résolveurs. Dans le résolveur sayHello, la valeur transmise au paramètre name est accessible via args. Pour accéder aux fonctions de résolution en dehors du module, l'objet Requête doit être exporté à l'aide de module.exports.

Étape 4 - Exécutez l'application

Créez un fichier server.js. Reportez-vous à l'étape 8 du chapitre Configuration de l'environnement. Exécutez la commande npm start dans le terminal. Le serveur sera opérationnel sur le port 9000. Ici, nous utilisons GraphiQL comme client pour tester l'application.

Ouvrez le navigateur et saisissez l'URL http://localhost:9000/graphiql. Tapez la requête suivante dans l'éditeur -

{
   greeting,
   sayHello(name:"Mohtashim")
}

La réponse du serveur est donnée ci-dessous -

{
   "data": {
      "greeting": "Hello GraphQL  From TutorialsPoint !!",
      "sayHello": "Hi Mohtashim GraphQL server says Hello to you!!"
   }
}

Configuration du client

Ouvrez un nouveau terminal pour le client. Le terminal serveur doit continuer à fonctionner avant d'exécuter l'application client. L'application React fonctionnera sur le port numéro 3000 et l'application serveur sur le port numéro 9000.

Étape 1 - Créer un projet React hello-world-client

Dans le terminal client, tapez la commande suivante -

npx create-react-app hello-world-client

Cela installera tout le nécessaire pour une application de réaction typique. lenpx utilité et create-react-apptool créer un projet avec le nom hello-world-client. Une fois l'installation terminée, ouvrez le projet dans VSCode.

Étape 2 - Démarrez hello-world-client

Changez le chemin du dossier actuel dans le terminal en hello-world-client. Tapez npm start pour lancer le projet. Cela exécutera un serveur de développement sur le port 3000 et ouvrira automatiquement le navigateur et chargera la page d'index.

Ceci est montré dans la capture d'écran ci-dessous -

Étape 3 - Modifier le composant de l'application

Dans le dossier App.js dans le dossier src, ajoutez deux fonctions, une pour charger le message d'accueil et une autre pour charger les messages sayHello.

Voici la fonction loadGreeting qui envoie une requête GraphQL pour le message d'accueil.

async function loadGreeting() {
   const response = await fetch('http://localhost:9000/graphql', {
      method:'POST',

      headers:{'content-type':'application/json'},
      body:JSON.stringify({query:'{greeting}'})
   })

   const rsponseBody = await response.json();
   return rsponseBody.data.greeting;

   console.log("end of function")
}

Voici le loadSayhello fonction qui envoie une requête GraphQL pour sayHello -

async function  loadSayhello(name) {
   const response = await fetch('http://localhost:9000/graphql', {
      method:'POST',
      headers:{'content-type':'application/json'},
      body:JSON.stringify({query:`{sayHello(name:"${name}")}`})
   })
}

Le complet App.js le fichier est montré ci-dessous -

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

async function loadGreeting() {
   const response =  await fetch('http://localhost:9000/graphql', {
      method:'POST',
      headers:{'content-type':'application/json'},
      body:JSON.stringify({query:'{greeting}'})
   })
   const rsponseBody =  await response.json();
   return rsponseBody.data.greeting;
   console.log("end of function")
}

async function  loadSayhello(name) {
   const response =  await fetch('http://localhost:9000/graphql', {
      method:'POST',
      headers:{'content-type':'application/json'},
      body:JSON.stringify({query:`{sayHello(name:"${name}")}`})
   })
   const rsponseBody =  await response.json();
   return rsponseBody.data.sayHello;
}

class App extends Component {
   constructor(props) {
      super(props);
      this.state =  {greetingMessage:'',sayHelloMessage:'',userName:''}
      this.updateName =  this.updateName.bind(this);
      this.showSayHelloMessage =  this.showSayHelloMessage.bind(this);
      this.showGreeting =  this.showGreeting.bind(this);
   }
   
   showGreeting() {
      loadGreeting().then(g => this.setState({greetingMessage:g+" :-)"}))
   }
   
   showSayHelloMessage() {
      const name = this.state.userName;
      console.log(name)
      loadSayhello(name).then(m => this.setState({sayHelloMessage:m}))
   }
   
   updateName(event) {
      this.setState({userName:event.target.value})
   }
   render() {
      return (
         <div className = "App">
            <header className = "App-header">
               <img src = {logo} className = "App-logo" alt = "logo" />
               <h1 className = "App-title">Welcome to React</h1>
            </header>
            <br/><br/>
            <section>
               <button id = "btnGreet" onClick = {this.showGreeting}>Greet</button>
               <br/> <br/>
               <div id = "greetingDiv">
                  <h1>{this.state.greetingMessage}</h1>
               </div>
            </section>
            
            <hr/>
            
            <section>
               Enter a name:<input id = "txtName" type = "text" onChange = {this.updateName}
               value = {this.state.userName}/>
               <button id = "btnSayhello" onClick = {this.showSayHelloMessage}>SayHello</button>
               <br/>
               user name is:{this.state.userName}    <br/>
               <div id = "SayhelloDiv">
                  <h1>{this.state.sayHelloMessage}</h1>
               </div>
            </section>
         </div>
      );
   }
}

export default App;

Une fois que les deux applications sont en cours d'exécution, cliquez sur le bouton de bienvenue. Ensuite, entrez un nom dans la zone de texte et cliquez sur le bouton sayHello. La sortie sera comme indiqué ci-dessous -

Nous avons utilisé Apollo Server pour créer une spécification graphql côté serveur. Il est rapide et facile de créer un serveur GraphQL prêt pour la production. Maintenant, comprenons le côté client.

Apollo Client est le meilleur moyen d'utiliser GraphQL pour créer des applications clientes. Le client est conçu pour aider les développeurs à créer rapidement une interface utilisateur qui récupère les données avec GraphQL et peut être utilisée avec n'importe quel frontal JavaScript.

Apollo Client prend en charge les plates-formes suivantes -

Sr.No. Plateforme et cadre
1

Javascript

Réagir, angulaire, vue, météore, braise

2

WebComponents

Polymère, lit-apollo

3

Native Mobile

Android natif avec Java, iOS natif avec Swift

La mise en cache est l'une des principales fonctionnalités d'Apollo Client. apollo-boost est un package pratique qui apporte un tas d'autres dépendances.

Illustration

Voyons comment utiliser Apollo Client pour créer des applications clientes en suivant les étapes suivantes -

Configuration du serveur

Nous devons suivre les étapes ci-dessous pour configurer un serveur -

Étape 1 - Téléchargez et installez les dépendances requises pour le projet

Créez un dossier apollo-server-app. Changez votre répertoire en apollo-server-app depuis le terminal. Ensuite, suivez les étapes 3 à 5 expliquées dans le chapitre Configuration de l'environnement.

Étape 2 - Créer un schéma

Ajouter schema.graphql fichier dans le dossier du projet apollo-server-app et ajoutez le code suivant -

type Query
{
   students:[Student]
}

type Student {
   id:ID!
   firstName:String
   lastName:String
   college:College
}

type College {
   id:ID!
   name:String
   location:String
   rating:Float
}

Étape 3 - Ajouter des résolveurs

Créer un fichier resolvers.js dans le dossier du projet et ajoutez le code suivant -

const db = require('./db')

const Query = {
   //resolver function for students returns list
   students:() => db.students.list(),
}

const Student = {
   college:(root) => {
      return db.colleges.get(root.collegeId);
   }
}
module.exports = {Query,Student}

Étape 4 - Exécutez l'application

Créer un server.jsfichier. Reportez-vous à l'étape 8 du chapitre Configuration de l'environnement. Exécutez la commande  npm start  dans le terminal. Le serveur sera opérationnel sur le port 9000. Ici, nous utiliserons GraphiQL comme client pour tester l'application.

Ouvrez le navigateur et saisissez l'URL http://localhost:9000/graphiql. Tapez la requête suivante dans l'éditeur.

{
   students{
      id
      firstName
      college{
         name
      }
   }
}

La réponse à la requête est la suivante -

{
   "data": {
      "students": [
         {
            "id": "S1001",
            "firstName": "Mohtashim",
            "college": {
               "name": "CUSAT"
            }
         },
         
         {
            "id": "S1002",
            "firstName": "Kannan",
            "college": {
               "name": "AMU"
            }
         },
         
         {
            "id": "S1003",
            "firstName": "Kiran",
            "college": {
               "name": "AMU"
            }
         }
      ]
   }
}

Configuration du client

Ouvrez un nouveau terminal pour le client. Le terminal serveur doit continuer à fonctionner avant d'exécuter l'application client. L'application React fonctionnera sur le port numéro 3000 et l'application serveur sur le port numéro 9000.

Étape 1 - Créer une application React

Dans le terminal client, tapez la commande suivante -

npx create-react-app hello-world-client

Cela installera tout le nécessaire pour une application de réaction typique. L'utilitaire npx et l'outil create-react-app créent un projet avec un nomhello-world-client. Une fois l'installation terminée, ouvrez le projet dans VSCode.

Étape 2 - Démarrez hello-world-client

Modifiez le chemin du dossier actuel dans le terminal en hello-world-client. Tapez npm start pour lancer le projet. Cela exécutera un serveur de développement sur le port 3000 et ouvrira automatiquement le navigateur et chargera la page d'index.

Ceci est montré dans la capture d'écran ci-dessous -

Étape 3 - Installer les bibliothèques clientes Apollo

Pour installer un client Apollo, ouvrez un nouveau terminal et soyez dans le chemin du dossier du projet actuel. Tapez la commande suivante -

npm install apollo-boost graphql

Cela téléchargera les bibliothèques graphql côté client ainsi que le package Apollo Boost. Nous pouvons vérifier cela en tapant npm view dans les dépendances apollo-boost. Cela aura de nombreuses dépendances comme indiqué ci-dessous -

{
   'apollo-cache': '^1.1.15',
   'apollo-cache-inmemory': '^1.2.8',
   'apollo-client': '^2.4.0',
   'apollo-link': '^1.0.6',
   'apollo-link-error': '^1.0.3',
   'apollo-link-http': '^1.3.1',
   'apollo-link-state': '^0.4.0',
   'graphql-tag': '^2.4.2'
}

Nous pouvons clairement voir que la bibliothèque Apollo-Client est installée.

Étape 4 - Modifier le composant d'application dans le fichier index.js

Avec Apollo Client, nous pouvons appeler directement le serveur sans utiliser Fetch API. De plus, les requêtes et les mutations ne doivent pas être incorporées dans une chaîne faite avec une notation de graduation arrière. C'est parce que, legqlLa fonction analyse directement les requêtes. Cela signifie qu'un programmeur peut directement écrire des requêtes de la même manière lors de l'écriture de requêtes dans l'outil GraphiQL. gql est une fonction de balise qui analysera la chaîne de modèle écrite en notation rétrograde dans l'objet de requête graphql. La méthode de requête Apollo Client renvoie une promesse.

L'extrait de code suivant montre comment importer Apollo Client -

import {ApolloClient, HttpLink, InMemoryCache} from 'apollo-boost'

const endPointUrl = 'http://localhost:9000/graphql'
const client = new ApolloClient({
   link: new HttpLink({uri:endPointUrl}),
   cache:new InMemoryCache()
});

Dans le chapitre précédent, nous avons expliqué comment utiliser Fetch API pour les requêtes HTTP. Le code suivant montre comment utilisergqlfonction. leloadStudentsAsync La fonction utilise le client graphql pour interroger le serveur.

async function loadStudentsAsync() {
   const query = gql`
   {
      students{
         id
         firstName
         lastName
         college{
            name
         }
      }
   }`
   const {data} = await client.query({query}) ;
   return data.students;
}

Il vous suffit de garder le index.js dans srcdossier et index.html dans le dossier public; tous les autres fichiers générés automatiquement peuvent être supprimés.

La structure des répertoires est donnée ci-dessous -

hello-world-client /
   -->node_modules
   -->public
         index.html
   -->src
         index.js
   -->package.json

Voici le index.js dans l'application React -

import React, {Component} from 'react';
import ReactDOM from 'react-dom';

// apollo client

import {ApolloClient, HttpLink, InMemoryCache} from 'apollo-boost'
import gql from 'graphql-tag'

const endPointUrl = 'http://localhost:9000/graphql'
const client = new ApolloClient({
   link: new HttpLink({uri:endPointUrl}),
   cache:new InMemoryCache()
});

async function loadStudentsAsync() {
   const query = gql`
   {
      students{
         id
         firstName
         lastName
         college{
            name
         }
      }
   }
   `
   const {data} = await client.query({query}) ;
   return data.students;
}
class  App  extends Component {
   constructor(props) {
      super(props);
      this.state = {
         students:[]
      }
      this.studentTemplate =  [];
   }
   async loadStudents() {
      const studentData =  await loadStudentsAsync();
      this.setState({
         students: studentData
      })
      console.log("loadStudents")
   }
   render() {
      return(
         <div>
            <input type = "button"  value = "loadStudents" onClick = {this.loadStudents.bind(this)}/>
            <div>
               <br/>
               <hr/>
               <table border = "3">
                  <thead>
                     <tr>
                        <td>First Name</td>
                        <td>Last Name</td>
                        <td>college Name</td>
                     </tr>
                  </thead>
                  
                  <tbody>
                     {
                        this.state.students.map(s => {
                           return (
                              <tr key = {s.id}>
                                 <td>
                                    {s.firstName}
                                 </td>
                                 <td>
                                    {s.lastName}
                                 </td>
                                 <td>
                                    {s.college.name}
                                 </td>
                              </tr>
                           )
                        })
                     }
                  </tbody>
               </table>
            </div>
         </div>
      )
   }
}
ReactDOM.render(<App/>, document.getElementById('root'));

L'application react chargera les étudiants à partir du serveur GraphQL, une fois que nous cliquons sur le bouton loadStudents comme indiqué ci-dessous -

L'authentification est le processus ou l'action de vérification de l'identité d'un utilisateur ou d'un processus. Il est important qu'une application authentifie un utilisateur pour s'assurer que les données ne sont pas disponibles pour un utilisateur anonyme. Dans cette section, nous apprendrons comment authentifier un client GraphQL.

Express JWT

Dans cet exemple, nous utiliserons jQuery pour créer une application cliente. Pour authentifier les demandes, nous utiliserons express-jwt module côté serveur.

Le module express-jwt est un middleware qui vous permet d'authentifier les requêtes HTTP à l'aide de jetons JWT. JSON Web Token (JWT) est une longue chaîne qui identifie l'utilisateur connecté.

Une fois que l'utilisateur se connecte avec succès, le serveur génère un jeton JWT. Ce jeton identifie distinctement un journal. En d'autres termes, le jeton est une représentation de l'identité de l'utilisateur. Ainsi, la prochaine fois, lorsque le client arrive sur le serveur, il doit présenter ce jeton pour obtenir les ressources nécessaires. Le client peut être une application mobile ou une application Web.

Illustration

Nous suivrons une procédure par étapes pour comprendre cette illustration.

Configuration du serveur

Voici les étapes de configuration du serveur -

Étape 1 - Téléchargez et installez les dépendances requises pour le projet

Créer un dossier auth-server-app. Changez votre répertoire en auth-server-app depuis le terminal. Suivez les étapes 3 à 5 expliquées dans le chapitre Configuration de l'environnement.

Étape 2 - Créer un schéma

schema.graphql auth-server-app
type Query
{
   greetingWithAuth:String
}

Étape 3 - Ajouter des résolveurs

Créer un fichier resolvers.js dans le dossier du projet et ajoutez le code suivant -

Le résolveur vérifiera si un objet utilisateur authentifié est disponible dans l'objet de contexte de GraphQL. Cela déclenchera une exception si un utilisateur authentifié n'est pas disponible.

const db = require('./db')

const Query = {
   greetingWithAuth:(root,args,context,info) => {

      //check if the context.user is null
      if (!context.user) {
         throw new Error('Unauthorized');
      }
      return "Hello from TutorialsPoint, welcome back : "+context.user.firstName;
   }
}

module.exports = {Query}

Étape 4 - Créer un fichier Server.js

L'intergiciel d'authentification authentifie les appelants à l'aide d'un jeton Web JSON. L'URL pour l'authentification est http://localhost:9000/login.

Ceci est une opération post. L'utilisateur doit soumettre son email et son mot de passe qui seront validés depuis le backend. Si un jeton valide est généré à l'aide de la méthode jwt.sign, le client devra l'envoyer dans l'en-tête pour les demandes suivantes.

Si le jeton est valide, req.user sera défini avec l'objet JSON décodé pour être utilisé par un middleware ultérieur pour l'autorisation et le contrôle d'accès.

Le code suivant utilise deux modules - jsonwebtoken et express-jwt pour authentifier les requêtes -

  • Lorsque l'utilisateur clique sur le greetbouton, une requête pour la route / graphql est émise. Si l'utilisateur n'est pas authentifié, il sera invité à s'authentifier.

  • L'utilisateur reçoit un formulaire qui accepte l'identifiant et le mot de passe de l'e-mail. Dans notre exemple, la route / login est responsable de l'authentification de l'utilisateur.

  • La route / login vérifie si une correspondance est trouvée dans la base de données pour les informations d'identification fournies par l'utilisateur.

  • Si les informations d'identification ne sont pas valides, une exception HTTP 401 est renvoyée à l'utilisateur.

  • Si les informations d'identification sont valides, un jeton est généré par le serveur. Ce jeton est envoyé dans le cadre de la réponse à l'utilisateur. Ceci est fait par la fonction jwt.sign.

const expressJwt = require('express-jwt');
const jwt = require('jsonwebtoken');

//private key
const jwtSecret = Buffer.from('Zn8Q5tyZ/G1MHltc4F/gTkVJMlrbKiZt', 'base64');

app.post('/login', (req, res) => {
   const {email, password} = req.body;
   
   //check database
   const user = db.students.list().find((user) =>  user.email === email);
   if (!(user && user.password === password)) {
      res.sendStatus(401);
      return;
   }
   
   //generate a token based on private key, token doesn't have an expiry
   const token = jwt.sign({sub: user.id}, jwtSecret);
   res.send({token});
});

Pour chaque requête, la fonction app.use () sera appelée. Cela invoquera à son tour le middleware expressJWT. Ce middleware décodera le jeton Web JSON. L'ID utilisateur stocké dans le jeton sera récupéré et stocké en tant qu'utilisateur de propriété dans l'objet de requête.

//decodes the JWT and stores in request object
app.use(expressJwt({
   secret: jwtSecret,
   credentialsRequired: false
}));

Pour rendre disponible la propriété utilisateur dans le contexte GraphQL, cette propriété est affectée au context objet comme indiqué ci-dessous -

//Make req.user available to GraphQL context
app.use('/graphql', graphqlExpress((req) => ({
   schema,
   context: {user: req.user &&apm; db.students.get(req.user.sub)}
})));

Créer server.js dans le chemin du dossier actuel. Le fichier server.js complet est le suivant -

const bodyParser = require('body-parser');
const cors = require('cors');
const express = require('express');
const expressJwt = require('express-jwt'); //auth
const jwt = require('jsonwebtoken'); //auth
const db = require('./db');

var port = process.env.PORT || 9000
const jwtSecret = Buffer.from('Zn8Q5tyZ/G1MHltc4F/gTkVJMlrbKiZt', 'base64');
const app = express();

const fs = require('fs')
const typeDefs = fs.readFileSync('./schema.graphql',{encoding:'utf-8'})
const resolvers = require('./resolvers')
const {makeExecutableSchema} = require('graphql-tools')

const schema = makeExecutableSchema({typeDefs, resolvers})

app.use(cors(), bodyParser.json(), expressJwt({
   secret: jwtSecret,
   credentialsRequired: false
}));

const  {graphiqlExpress,graphqlExpress} = require('apollo-server-express')

app.use('/graphql', graphqlExpress((req) => ({
   schema,
   context: {user: req.user && db.students.get(req.user.sub)}
})));
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))

//authenticate students
app.post('/login', (req, res) => {
   const email = req.body.email;
   const password = req.body.password;

   const user = db.students.list().find((user) =>  user.email === email);
   if (!(user && user.password === password)) {
      res.sendStatus(401);
      return;
   }
   const token = jwt.sign({sub: user.id}, jwtSecret);
   res.send({token});
});

app.listen(port, () => console.info(`Server started on port ${port}`));

Étape 5 - Exécutez l'application

Exécutez la commande  npm start dans le terminal. Le serveur sera opérationnel sur le port 9000. Ici, nous utilisons GraphiQL comme client pour tester l'application.

Ouvrez le navigateur et saisissez l'URL http://localhost:9000/graphiql. Tapez la requête suivante dans l'éditeur -

{
   greetingWithAuth
}

Dans la réponse ci-dessous, nous avons obtenu une erreur car nous ne sommes pas un utilisateur authentifié.

{
   "data": {
      "greetingWithAuth": null
   },
   "errors": [
      {
         "message": "Unauthorized",
         "locations": [
            {
               "line": 2,
               "column": 3
            }
         ],
         "path": [
            "greetingWithAuth"
         ]
      }
   ]
}

Dans la section suivante, créons une application client pour s'authentifier.

Configuration du client JQuery

Dans l'application cliente, un bouton de bienvenue est fourni qui invoquera le schéma greetingWithAuth. Si vous cliquez sur le bouton sans connexion, cela vous donnera le message d'erreur ci-dessous -

Une fois que vous vous connectez avec un utilisateur disponible dans la base de données, l'écran suivant apparaîtra -

Accéder greeting, nous devons d'abord accéder à l'URL http://localhost:9000/login itinéraire comme ci-dessous.

La réponse contiendra le jeton généré par le serveur.

$.ajax({
   url:"http://localhost:9000/login",
   contentType:"application/json",
   type:"POST",
   data:JSON.stringify({email,password}),
   success:function(response) {
      loginToken = response.token;
      $('#authStatus') .html("authenticated successfully") .css({"color":"green",'font-weight':'bold'}); $("#greetingDiv").html('').css({'color':''});
   },
   error:(xhr,err) =>  alert('error')
})

Après une connexion réussie, nous pouvons accéder à greetingWithAuth schéma comme indiqué ci - dessous. Il devrait y avoir un en-tête d'autorisation pour toutes les demandes ultérieures avec un jeton de support.

{ 
   url: "http://localhost:9000/graphql",
   contentType: "application/json",
   headers: {"Authorization": 'bearer '+loginToken},  type:'POST',
   data: JSON.stringify({
   query:`{greetingWithAuth}`
}

Voici le code pour index.html -

<!DOCTYPE html>
<html>
   <head>
      <script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      <script>
         $(document).ready(function() { let loginToken = ""; $("#btnGreet").click(function() {
                  $.ajax({url: "http://localhost:9000/graphql", contentType: "application/json", headers: {"Authorization": 'bearer '+loginToken}, type:'POST', data: JSON.stringify({ query:`{greetingWithAuth}` }), success: function(result) { $("#greetingDiv").html("<h1>"+result.data.greetingWithAuth+"</h1>")
                  },
                  error:function(jQxhr,error) {
                     if(jQxhr.status == 401) {
                        $("#greetingDiv").html('please authenticate first!!') .css({"color":"red",'font-weight':'bold'}) return; } $("#greetingDiv").html('error').css("color","red");
                  }
               });
            });
            $('#btnAuthenticate').click(function() { var email = $("#txtEmail").val();
               var password =  $("#txtPwd").val(); if(email && password) { $.ajax({
                     url:"http://localhost:9000/login",
                     contentType:"application/json",
                     type:"POST",
                     data:JSON.stringify({email,password}),
                     success:function(response) {
                        loginToken =  response.token;
                        $('#authStatus') .html("authenticated successfully") .css({"color":"green",'font-weight':'bold'}); $("#greetingDiv").html('').css({'color':''});
                     },
                     error:(xhr,err) =>  alert('error')
                  })
               }else alert("email and pwd empty")
            })
         });
      </script>
   </head>
   
   <body>
      <h1> GraphQL Authentication </h1>
      <hr/>
      <section>
         <button id = "btnGreet">Greet</button>
         <br/> <br/>
         <div id = "greetingDiv"></div>
      </section>
      <br/> <br/> <br/>
      <hr/>
      
      <section id = "LoginSection">
         <header>
            <h2>*Login first to  access greeting </h2>
         </header>
         <input type = "text" value = "[email protected]" placeholder = "enter email" id = "txtEmail"/>
         <br/>
         
         <input type = "password" value = "pass123" placeholder = "enter password" id = "txtPwd"/>
         <br/>
         
         <input type = "button" id = "btnAuthenticate"  value = "Login"/>
         <p id = "authStatus"></p>
      </section>
   </body>
</html>

La mise en cache est le processus de stockage des données dans une zone de stockage temporaire appelée cache. Lorsque vous revenez sur une page que vous avez récemment visitée, le navigateur peut récupérer ces fichiers à partir du cache plutôt que du serveur d'origine. Cela économise votre temps et votre réseau du fardeau du trafic supplémentaire.

Les applications clientes interagissant avec GraphQL sont responsables de la mise en cache des données à leur extrémité. Un modèle possible pour cela est de réserver un champ, comme id, pour être un identifiant globalement unique.

Cache InMemory

InMemoryCache est un magasin de données normalisé couramment utilisé dans les applications clientes GraphQL sans utilisation d'une autre bibliothèque comme Redux.

L'exemple de code pour utiliser InMemoryCache avec ApolloClient est donné ci-dessous -

import {ApolloClient, HttpLink, InMemoryCache} from 'apollo-boost'
const cache = new InMemoryCache();

const client = new ApolloClient({
   link: new HttpLink(),
   cache
});

Le constructeur InMemoryCache prend un objet de configuration facultatif avec des propriétés pour personnaliser votre cache.

Sr.No. Paramètre et description
1

addTypename

Un booléen pour déterminer s'il faut ajouter __typename au document (par défaut: true)

2

dataIdFromObject

Une fonction qui prend un objet de données et renvoie un identifiant unique à utiliser lors de la normalisation des données dans le magasin

3

fragmentMatcher

Par défaut, InMemoryCache utilise un sélecteur de fragments heuristique

4

cacheRedirects

Une carte de fonctions pour rediriger une requête vers une autre entrée du cache avant qu'une requête n'ait lieu.

Illustration

Nous allons créer une application d'une seule page dans ReactJS avec deux onglets - un pour l'onglet d'accueil et un autre pour les étudiants. L'onglet étudiants chargera les données depuis une API serveur GraphQL. L'application interrogera les données des étudiants lorsque l'utilisateur navigue de l'onglet d'accueil à l'onglet étudiants. Les données résultantes seront mises en cache par l'application.

Nous interrogerons également l'heure du serveur en utilisant getTimechamp pour vérifier si la page est mise en cache. Si des données sont renvoyées depuis le cache, la page affichera l'heure de la toute première requête envoyée au serveur. Si les données sont le résultat d'une nouvelle demande adressée au serveur, elles afficheront toujours la dernière heure du serveur.

Configuration du serveur

Voici les étapes de configuration du serveur -

Étape 1 - Téléchargez et installez les dépendances requises pour le projet

Créer un dossier cache-server-app. Changez votre répertoire en cache-server-app depuis le terminal. Suivez les étapes 3 à 5 expliquées dans le chapitre Configuration de l'environnement.

Étape 2 - Créer un schéma

Ajouter schema.graphql fichier dans le dossier du projet cache-server-app et ajoutez le code suivant -

type Query {
   students:[Student]
   getTime:String
}

type Student {
   id:ID!
   firstName:String
   lastName:String
   fullName:String
}

Étape 3 - Ajouter des résolveurs

Créez un fichier resolvers.js dans le dossier du projet et ajoutez le code suivant -

const db = require('./db')

const Query = {
      students:() => db.students.list(),
      getTime:() => {
      const today = new Date();
      var h = today.getHours();
      var m = today.getMinutes();
      var s = today.getSeconds();
      return `${h}:${m}:${s}`;
   }
}
module.exports = {Query}

Étape 4 - Exécutez l'application

Créez un fichier server.js. Reportez-vous à l'étape 8 du chapitre Configuration de l'environnement. Exécutez la commande npm start dans le terminal. Le serveur sera opérationnel sur le port 9000. Ici, nous utiliserons GraphiQL comme client pour tester l'application.

Ouvrez le navigateur et entrez l'URL http://localhost:9000/graphiql. Tapez la requête suivante dans l'éditeur -

{
   getTime
   students {
      id
      firstName
   }
}

L'exemple de réponse montre les noms des étudiants et l'heure du serveur.

{
   "data": {
      "getTime": "22:18:42",
      "students": [
         {
            "id": "S1001",
            "firstName": "Mohtashim"
         },
         {
            "id": "S1002",
            "firstName": "Kannan"
         },
         {
            "id": "S1003",
            "firstName": "Kiran"
         }
      ]
   }
}

Configuration du client ReactJS

Ouvrez un nouveau terminal pour le client. Le terminal serveur doit continuer à fonctionner avant d'exécuter l'application client. L'application React fonctionnera sur le port numéro 3000 et l'application serveur sur le port numéro 9000.

Étape 1 - Créer une application React

Dans le terminal client, tapez la commande suivante -

npx create-react-app hello-world-client

Cela installera tout le nécessaire pour une application de réaction typique. lenpx utility et create-react-apptools crée un projet avec le nom hello-world-client. Une fois l'installation terminée, ouvrez le projet dans VSCode.

Installez les modules de routeur pour réagir en utilisant la commande suivante - npm install react-router-dom.

Étape 2 - Démarrez hello-world-client

Changez le chemin du dossier actuel dans le terminal en hello-world-client. Tapez npm start pour lancer le projet. Cela exécutera un serveur de développement sur le port 3000 et ouvrira automatiquement le navigateur et chargera la page d'index.

Ceci est montré dans la capture d'écran ci-dessous -

Étape 3 - Installer les bibliothèques clientes Apollo

Pour installer un client Apollo, ouvrez un nouveau terminal et soyez dans le chemin du dossier du projet actuel. Tapez la commande suivante -

npm install apollo-boost graphql

Cela téléchargera les bibliothèques graphql côté client ainsi que le package Apollo Boost. Nous pouvons vérifier cela en tapant npm view dépendances apollo-boost. Cela aura de nombreuses dépendances comme indiqué ci-dessous -

{ 
   'apollo-cache': '^1.1.15',
   'apollo-cache-inmemory': '^1.2.8',
   'apollo-client': '^2.4.0',
   'apollo-link': '^1.0.6',
   'apollo-link-error': '^1.0.3',
   'apollo-link-http': '^1.3.1',
   'apollo-link-state': '^0.4.0',
   'graphql-tag': '^2.4.2' 
}

Nous pouvons clairement voir que la bibliothèque apollo-client est installée.

Étape 4 - Modifier le composant d'application dans le fichier index.js

Pour une application de réaction simple, il vous suffit de conserver le index.js dans src dossier et index.htmldans un dossier public; tous les autres fichiers générés automatiquement peuvent être supprimés.

La structure des répertoires est donnée ci-dessous -

hello-world-client /
   -->node_modules
   -->public
      index.html
   -->src
      index.js
      students.js
   -->package.json

Ajoutez un fichier supplémentaire student.js qui contiendra le composant Elèves. Les détails de l'étudiant sont récupérés via le composant étudiant. Dans le composant App, nous utilisons un HashRouter.

Voici le index.js dans l'application React -

import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import {HashRouter, Route, Link} from 'react-router-dom'

//components
import Students from './students'
class App extends Component {
   render() {
      return(
         <div><h1>Home !!</h1>
         <h2>Welcome to React Application !! </h2>
         </div>
      )
   }
}

function getTime() {
   var d = new Date();
   return d.getHours()+":"+d.getMinutes()+":"+d.getSeconds()
}

const routes = <HashRouter>
   <div>
      <h4>Time from react app:{getTime()}</h4>
      <header>
         <h1>  <Link to="/">Home</Link> 
         <Link to = "/students">Students</Link>  </h1>
      </header>
      <Route exact path = "/students" component = {Students}></Route>
      <Route exact path = "/" component = {App}></Route>
   </div>
</HashRouter>

ReactDOM.render(routes, document.querySelector("#root"))

Étape 5 - Modifier les étudiants du composant dans Students.js

Dans le composant Élèves, nous utiliserons les deux approches suivantes pour charger des données -

  • Fetch API (loadStudents_noCache) - Cela déclenchera une nouvelle demande à chaque fois que vous cliquerez sur l'onglet étudiant.

  • Apollo Client (loadWithApolloclient) - Cela récupérera les données du cache.

Ajouter une fonction loadWithApolloclientquelles requêtes pour les étudiants et l'heure du serveur. Cette fonction activera la mise en cache. Ici, nous utilisons une fonction gql pour analyser la requête.

async loadWithApolloclient() {
   const query = gql`{
      getTime
      students {
         id
         firstName
      }
   }`;

   const {data} = await  client.query({query})
   return data;
}

le Fetch APIest une interface simple pour récupérer des ressources. Fetch facilite la création de requêtes Web et la gestion des réponses qu'avec l'ancien XMLHttpRequest. La méthode suivante montre le chargement des données directement à l'aide de Fetch api -

async  loadStudents_noCache() {
      const response = await fetch('http://localhost:9000/graphql', {
      method:'POST',
      headers:{'content-type':'application/json'},
      body:JSON.stringify({query:`{
         getTime
         students {
            id
            firstName
         }
      }`})
   })

   const rsponseBody = await response.json();
   return rsponseBody.data;
}

Dans le constructeur de StudentsComponent, appelez le loadWithApolloClientméthode. Le complet Student.js le fichier est ci-dessous -

import React, {Component} from 'react';
import { Link} from 'react-router-dom'

//Apollo Client
import {ApolloClient, HttpLink, InMemoryCache} from 'apollo-boost'
import gql from 'graphql-tag'
const client = new ApolloClient({
   link: new HttpLink({uri:`http://localhost:9000/graphql`}),
   cache:new InMemoryCache()
})

class Students extends Component {
   constructor(props) {
      super(props);
      this.state = {
         students:[{id:1,firstName:'test'}],
         serverTime:''
      }
      this.loadWithApolloclient().then(data => {
         this.setState({
            students:data.students,
            serverTime:data.getTime
         })
      })
   }
   
   async  loadStudents_noCache() {
      const response = await fetch('http://localhost:9000/graphql', {
         method:'POST',
         headers:{'content-type':'application/json'},
         body:JSON.stringify({query:`{
            getTime
            students {
               id
               firstName
            }
         }`})
      })
      const rsponseBody =  await response.json();
      return rsponseBody.data;
   }
   
   async loadWithApolloclient() {
      console.log("inside apollo client function")
      const query = gql`{
         getTime
         students {
            id
            firstName
         }
      }`;
      const {data} = await  client.query({query})
      return data;
   }
   
   render() {
      return(
         <div>
            <h3>Time from GraphQL server :{this.state.serverTime}</h3>
            <p>Following Students Found </p>
            <div>
               <ul>
                  {
                     this.state.students.map(s => {
                        return(
                           <li key = {s.id}>
                              {s.firstName}
                           </li>
                        )
                     })
                  }
               </ul>
            </div>
         </div>
      )
   }
}
export default Students

Étape 6 - Exécutez l'application React avec npm start

Vous pouvez tester l'application react en passant de l'onglet d'accueil à l'onglet étudiants. Une fois que l'onglet étudiants est chargé avec les données du serveur. Il mettra en cache les données. Vous pouvez le tester en passant plusieurs fois de l'onglet Accueil à l'onglet Élèves. La sortie sera comme indiqué ci-dessous -

Si vous avez d'abord chargé la page des élèves en saisissant l'URL, http://localhost:3000/#/students, vous pouvez voir que le temps de chargement de l'application react et de GraphQL serait approximativement le même. Après cela, si vous passez en vue d'accueil et revenez sur le serveur GraphQL, l'heure ne changera pas. Cela montre que les données sont mises en cache.

Étape 7 - Changez l'appel loadWithApolloclient pour loadStudents_noCache

Si vous modifiez la méthode de chargement en loadStudents_noCachedans le constructeur de StudentComponent, la sortie ne mettra pas en cache les données. Cela montre la différence entre la mise en cache et la non-mise en cache.

this.loadStudents_noCache().then(data => {
   this.setState({
      students:data.students,
      serverTime:data.getTime
   })
})

À partir de la sortie ci-dessus, il est clair que si vous basculez entre les onglets, l'heure du serveur graphql sera toujours la plus récente, ce qui signifie que les données ne sont pas mises en cache.