Skip to content

Connecter une API à une app React.js, via GraphQL (schéma et environnement)

Notifications You must be signed in to change notification settings

corneliugaina/workshop-loveson-graphql

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 

Repository files navigation

workshop-loveson-graphql : Connecter une API à une app React.js, via GraphQL (schéma et environnement)

Workshop

Jeudi 11 juillet 2019. Présentation d'un workshop, dans le cadre de la formation BeCode, qui a pour sujet : affichage d'une API en ReactJS, via un schéma GraphQL. L'objectif est d'initier le participant à ce qu'est GraphQL, ses avantages, et la configuration d'un environnement de développement javascript; soit une application front-end React.js, connectée à une source de donnée requêtable (ici, une simple API JSON) via une schéma GraphQL situé dans un environnement serveur NodeJS + Express.

Le workshop est inspiré de l'instructeur youtubeur NetNinja, qui utilise MongoDB (donc le stack MERN : MongoDB, Express, React, Node).

Les instructeurs de ce workshop, Corneliu GAINA et Mathilde BAQUET, ont eu énormément des challenges à relever, mais également beaucoup de plaisir à le réaliser. Durée : 7 h.

Apercu des Technologies utilisées

React.js is a JavaScript library that allows us to construct user interfaces that are component-based and that can be dynamically updated depending on the state of an application. This allows us to create intentional, complex and yet organized user interfaces that fit nicely into the current state of modern web development.

GraphQL is a syntax that describes how to ask for data, and is generally used to load data from a server to a client. GraphQL has three main characteristics: It lets the client specify exactly what data it needs. It makes it easier to aggregate data from multiple sources.

Apollo Client is the best way to use GraphQL to build client applications. The client is designed to help you quickly build a UI that fetches data with GraphQL, and can be used with any JavaScript front-end. ... Universally compatible: Apollo works with any build setup, any GraphQL server, and any GraphQL schema.

Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices. Node.js is an open source, cross-platform runtime environment for developing server-side and networking applications.

Express.js handles things like cookies, parsing the request body, forming the response and handling routes. It also is the part of the application that listens to a socket to handle incoming requests. ... Express in a Node.js based framework which simplifies writing Server-side Code and Logic.

Corporate Face Actual ID GitHub LinkedIn
Mathilde BAQUET MathildeBa https://www.linkedin.com/in/mathilde-baquet-b44440122/
Corneliu GAINA corneliushka https://www.linkedin.com/in/corneliugaina/

Plan de la journée

Dans ce repo chaque étape est séparée sur des branches différentes. Aller directement à la dernière branche/étape pour le code intégral et toutes les insctructions depuis le début. La dernière étape finit la configuration et l'initiation à l'objectif du workshop, libre à l'utilisateur d'aller plus loin et expérimenter l'API et/ou d'utiliser d'autres sources de données.

introduction

GraphQL en 2 mots (cf. slides

Step1 - preparation du server GraphQL.

Step2 - preparation du serveur GraphQL (II)

Step3 - Mise en place du graphQL schema

Step4 - mise en place du RootQuery et de la resolve fonction

Step5 - Nouveau 'Type' et 'TypeRelation'

Strepsils - Remplacer les dummy datas par une API.

Strep7 - Ajout de REACT.js

Strep8 - Rendu des datas de l'API dans un component

Step1-preparation du server GraphQL.

Mise en place de l'environement express sur le port 4000.

const express = require('express'); // 1.

const app = express(); // 2.


app.listen(4000, () => { // 3. une fois installé nodemon, va "ecouter les changements" in browser: http://localhost:4000/graphql 
    console.log('now listening for request on port 4000');
})

Step2 - preparation du serveur GraphQL (II)

Mise en place du serveur GraphQL

  • installation du package express graphql-express
    (https://www.npmjs.com/package/express-graphql)
    npm install --save graphql express-graphql
  • importer express graphQL et on creer une fonction qui servira de noeud central/middleware et envera les requetes graphQL dans un seul endroit.
  • lancer l'application pour ecouter les mises a jour du serveur node
    nodemon app
  • RDV sur localhost:4000/graphql
const express = require('express'); // 1.
const graphqlHTTP = require('express-graphql'); // 4. création du serveur express qui va executer graphql api

const app = express(); // 2.

app.use('/graphql', graphqlHTTP({ // 5. fonction servant de noeud central/middleware qui va envoyer toutes les requetes graphql en un seul endroit
    // placer schema ici ulterieurement
}));

app.listen(4004, () => { // 3. une fois installé nodemon, va "ecouter les changements" in browser: http://localhost:4000/graphql 
    console.log('now listening for request on port 4004');
})   

Step3 - Mise en place du graphQL schema

affin de lancer quelque chose dans le serveur, il faudra quelque chose a executer.

  • dans le 'server' :
    mkdir schema
  • dans le 'schema' :
    touch schema.js
  • dans 'schema' on y importe graphQL
  • extraire/destructurer les objects de graphQL dont on aura besoin plus tard
  • importer les dummy datas
[
{id: 22,prenom: "Cedric",nom: "Van Hove",gitHub: "cevaho",linkedIn: "https://www.linkedin.com/in/c%C3%A9dric-van-hove-99250926/",promo: "johnson"},
{id: 1, prenom: "Maxime", nom: "Broodcoorens",gitHub: "Broodco", linkedIn: "https://www.linkedin.com/in/maxime-broodcoorens-783472168/", promo: "lovelace" },
{id: 2, prenom: "Emilie", nom: "Bialais",gitHub: "ebialais",linkedIn:"https://www.linkedin.com/in/emilie-bialais-b4b67658/", promo: "lovelace" },
{id: 3,prenom: "Pierre-Louis ",nom: "Picard",gitHub: "Pierre-Louis242",linkedIn:"https://www.linkedin.com/in/pierre-louis-picard-b30993a8/",promo: "lovelace"},
{id: 4,prenom: "Mathilde",nom: "Baquet",gitHub: "MathildeBa",linkedIn:"https://www.linkedin.com/in/mathilde-baquet",promo: "lovelace"},
{id: 19,prenom: "Antoine",nom: "Diambu",gitHub: "AntoineDia",linkedIn: "https://www.linkedin.com/in/antoine-diambu-402776178/",promo: "johnson" }
]
  • construction de notre premier type
const graphql = require('graphql'); // 1. on va attribuer à une variable le paquet npm graphql précédemment installé

const { GraphQLObjectType, 
        GraphQLString, 
        GraphQLSchema,
        GraphQLID,
        GraphQLList } = graphql; // 2. ici on va extraire les objets dont on a besoin du package graphql 


// 3. dummy data 
const octocats = [
    {id: 22,prenom: "Cedric",nom: "Van Hove",gitHub: "cevaho",linkedIn: "https://www.linkedin.com/in/c%C3%A9dric-van-hove-99250926/",promo: "johnson"},
    {id: 1, prenom: "Maxime", nom: "Broodcoorens",gitHub: "Broodco", linkedIn: "https://www.linkedin.com/in/maxime-broodcoorens-783472168/", promo: "lovelace" },
    {id: 2, prenom: "Emilie", nom: "Bialais",gitHub: "ebialais",linkedIn:"https://www.linkedin.com/in/emilie-bialais-b4b67658/", promo: "lovelace" },
    {id: 3,prenom: "Pierre-Louis ",nom: "Picard",gitHub: "Pierre-Louis242",linkedIn:"https://www.linkedin.com/in/pierre-louis-picard-b30993a8/",promo: "lovelace"},
    {id: 4,prenom: "Mathilde",nom: "Baquet",gitHub: "MathildeBa",linkedIn:"https://www.linkedin.com/in/mathilde-baquet",promo: "lovelace"},
    {id: 19,prenom: "Antoine",nom: "Diambu",gitHub: "AntoineDia",linkedIn: "https://www.linkedin.com/in/antoine-diambu-402776178/",promo: "johnson" }
]



// 4. on va créer deja notre 1er type dans le schema (UserType), on donne un nom à notre objet (octocat) + fields avec le type correspondant
const UserType = new GraphQLObjectType ({ 
    name: 'octocat',
    fields: () => ({
        id: {type: GraphQLID},
        prenom: {type: GraphQLString},
        nom: {type: GraphQLString},
        gitHub: {type: GraphQLString},
        linkedIn: {type: GraphQLString},
        promo: {type: GraphQLString}
    })
}); //!\ 

Step4 - mise en place du RootQuery et de la resolve fonction

Le RootQuery représente toutes les entrées possibles dans le GraphQL API et la fonction resolve pour teste la Query
Gandalf

  • installer la librairie 'lodash' : npm install lodash qui permet de modifier la DB dans l'array
    https://www.npmjs.com/package/lodash
  • importer lodash dans le fichier 'schema.js'
  • creation du nouvel objet GraphQL appelé RootQuery.
  • exporter le schema
  • dans la RootQuery on creer la fonction resolve
  • on return avec la methode 'lodash' la recherche de l'octocat lier a un certain ID
  • dans app.js on importe le schema(+ dans app.use) et y autoriser graphQL
  • Essayer dans Localhost/4000/graphql :
{
  octocat(id: 2) {
    nom
    prenom
  }
}   

app.js

const express = require('express'); // 1.
const graphqlHTTP = require('express-graphql'); // 4. création du serveur express qui va executer graphql api

const app = express(); // 2.

app.use('/graphql', graphqlHTTP({ // 5. fonction servant de noeud central/middleware qui va envoyer toutes les requetes graphql en un seul endroit
    // placer schema ici ulterieurement
}));

app.listen(4004, () => { // 3. une fois installé nodemon, va "ecouter les changements" in browser: http://localhost:4000/graphql 
    console.log('now listening for request on port 4004');
})

schema.js

const graphql = require('graphql'); // 1. on va attribuer à une variable le paquet npm graphql précédemment installé
const _ = require('lodash'); // 7. apres avoir installé lodash 


const { GraphQLObjectType, 
        GraphQLString, 
        GraphQLSchema,
        GraphQLInt, // cf. date 
        GraphQLID,
        GraphQLList } = graphql; // 2. ici on va extraire les objets dont on a besoin du package graphql 

// 3. dummy data 
const octocats = [
    {id: "22", prenom: "Cedric",nom: "Van Hove",gitHub: "cevaho",linkedIn: "https://www.linkedin.com/in/c%C3%A9dric-van-hove-99250926/",promo: "johnson"},
    {id: "1", prenom: "Maxime", nom: "Broodcoorens",gitHub: "Broodco", linkedIn: "https://www.linkedin.com/in/maxime-broodcoorens-783472168/", promo: "lovelace" },
    {id: "2", prenom: "Emilie", nom: "Bialais",gitHub: "ebialais",linkedIn:"https://www.linkedin.com/in/emilie-bialais-b4b67658/", promo: "lovelace" },
    {id: "3", prenom: "Pierre-Louis", nom: "Picard",gitHub: "Pierre-Louis242",linkedIn:"https://www.linkedin.com/in/pierre-louis-picard-b30993a8/",promo: "lovelace"},
    {id: "4", prenom: "Mathilde",nom: "Baquet",gitHub: "MathildeBa",linkedIn:"https://www.linkedin.com/in/mathilde-baquet",promo: "lovelace"},
    {id: "19", prenom: "Antoine",nom: "Diambu",gitHub: "AntoineDia",linkedIn: "https://www.linkedin.com/in/antoine-diambu-402776178/",promo: "johnson" }
]


// 4. on va créer deja notre 1er type dans le schema (UserType), on donne un nom à notre objet (octocat) + fields avec le type correspondant
const UserType = new GraphQLObjectType ({ 
    name: 'octocat',
    fields: () => ({
        id: {type: GraphQLString},
        prenom: {type: GraphQLString},
        nom: {type: GraphQLString},
        gitHub: {type: GraphQLString},
        linkedIn: {type: GraphQLString},
        promo: {type: GraphQLString}
    })
}); //!\ 


const RootQuery = new GraphQLObjectType({ // 5. represents all of the possible entry points into the GraphQL API
    name: 'RootQueryType', // on specifie le type 
    fields: { 
        octocat: {
            type: UserType,
            args: {id: {type: GraphQLID}}, //!\ si notre ID est un string, il mettre un integer (GraphQLInt) et parser
            resolve(parent, args){ // 8. lorsqu'on fera une query (dans GraphiQL), c'est la fonction resolve qui se lance
                return _.find(octocats, {id: args.id});
            }
        }
    }
})


module.exports = new GraphQLSchema({ // 6. ici on va exporter notre schèma 
    query: RootQuery,    
})

Step5 - Nouveau 'Type' et 'TypeRelation'

Connecter deux tableaux de données via la RootQuery.

Gandalf

  • more dummy datas(veilles BeCode).
  • creation d'un nouveau Type : 'WatchType'
  • on represente son entrée dans notre RootQuery
  • définir la relation entre nos deux types : 'UserType' et 'WatchType'
  • dans RootQuery fields on creer les listes pour afficher les dummy data (tableau)
  • dans le 'WatchType' on va creer le chemin pour trouver l'ID des Octocats(UserType) sous forme de liste et les infos qui s'en découlent
  • dans le 'UserType' on va cheer le chemin pour trouver l'ID des watches(WatchType) sous forme de liste et les infos qui s'en découlent

app.js

const express = require('express'); // 1.
const graphqlHTTP = require('express-graphql'); // 4. création du serveur express qui va executer graphql api
const schema = require('./schema/schema') // 6. une fois notre schema defini (cf. schema.js), on l'importe 

const app = express(); // 2.

app.use('/graphql', graphqlHTTP({ // 5. fonction servant de noeud central/middleware qui va envoyer toutes les requetes graphql en un seul endroit
    // placer schema ici et autoriser graphiql à se lancer
    schema,
    graphiql: true
}));

app.listen(4000, () => { // 3. une fois installé nodemon, va "ecouter les changements" in browser: http://localhost:4000/graphql 
    console.log('now listening for request on port 4000');
})
   
   

schema.js

const graphql = require('graphql'); // 1. on va attribuer à une variable le paquet npm graphql précédemment installé
const _ = require('lodash'); // 7. apres avoir installé lodash 

const { GraphQLObjectType, 
        GraphQLString, 
        GraphQLSchema,
        GraphQLInt, // cf. date 
        GraphQLID,
        GraphQLList } = graphql; // 2. ici on va extraire les objets dont on a besoin du package graphql 

// 3. dummy data 
const octocats = [
    {id: "22", prenom: "Cedric",nom: "Van Hove", gitHub: "cevaho",linkedIn: "https://www.linkedin.com/in/c%C3%A9dric-van-hove-99250926/",promo: "johnson"},
    {id: "1", prenom: "Maxime", nom: "Broodcoorens", gitHub: "Broodco", linkedIn: "https://www.linkedin.com/in/maxime-broodcoorens-783472168/", promo: "lovelace" },
    {id: "2", prenom: "Emilie", nom: "Bialais", gitHub: "ebialais",linkedIn:"https://www.linkedin.com/in/emilie-bialais-b4b67658/", promo: "lovelace" },
    {id: "3", prenom: "Pierre-Louis", nom: "Picard", gitHub: "Pierre-Louis242",linkedIn:"https://www.linkedin.com/in/pierre-louis-picard-b30993a8/",promo: "lovelace"},
    {id: "4", prenom: "Mathilde",nom: "Baquet", gitHub: "MathildeBa",linkedIn:"https://www.linkedin.com/in/mathilde-baquet",promo: "lovelace"},
    {id: "19", prenom: "Antoine",nom: "Diambu", gitHub: "AntoineDia",linkedIn: "https://www.linkedin.com/in/antoine-diambu-402776178/",promo: "johnson" }
]

const watches = [
    {id: "1", octocatId: "3", date: 190319, subject: "Power BI", link: "https://powerbi.microsoft.com/fr-fr/"},
    {id: "2", octocatId: "2", date: 150419, subject: "Black Hole", link:  "https://drive.google.com/open?id=1ZWgEnRzZyCS5RX0AoEPfinbIbmfAQo1Y-JT1E-CyRsU"},
    {id: "3", octocatId: "2", date: 250219, subject: "La minute santé", link: "https://docs.google.com/presentation/d/1bVct12Ttw16G7B-"},
    {id: "4", octocatId: "1", date: 180419, subject: "Back-end: choix d'une technologie", link: "https://slides.com/broodco/deck-1#/"},
    {id: "5", octocatId: "2", date: 20519, subject: "Performance", link: "https://docs.google.com/presentation/d/1g3YF0yUndVZ0n2wGrFxL_85ChPPFjcn0sTLiux2T6aI/edit?usp=sharing"},
    {id: "6", octocatId: "3", date: 40219, subject: "Photo Wake-up 3D, donner vie aux images", link:  "https://github.com/Pierre-louis242/The-Watch-"},
    {id: "7", octocatId: "1", date: 210219, subject: "Raspberry Pi", link: "https://www.raspberrypi.org/"}
]

// 4. on va créer deja notre 1er type dans le schema (UserType), on donne un nom à notre objet (octocat) + fields avec le type correspondant
const UserType = new GraphQLObjectType ({ 
    name: 'octocat',
    fields: () => ({
        id: {type: GraphQLID},
        prenom: {type: GraphQLString},
        nom: {type: GraphQLString},
        gitHub: {type: GraphQLString},
        linkedIn: {type: GraphQLString},
        promo: {type: GraphQLString},
        watches: {
            type: new GraphQLList(WatchType),
            resolve(parent, args){
                return _.filter(watches, { octocatId: parent.id});
            }}
    })
}); //!\ 

// 4.bis : type Watch
const WatchType = new GraphQLObjectType ({
    name: 'watch',
    fields: () => ({
        id: {type: GraphQLID},
        octocatId: { // 10. on va définir le type et matcher via le resolver avec l'octocat correspondant
            type: UserType,
            resolve(parent, args){ // on va chercher l'octocat associé
                // console.log(parent);
                return _.find(octocats, {id: parent.octocatId});
            }
        },
        date: {type: GraphQLInt},
        subject: {type: GraphQLString},
        link: {type: GraphQLString}

    })
}); 

// ROOTQUERY
const RootQuery = new GraphQLObjectType({ // 5. represents all of the possible entry points into the GraphQL API
    name: 'RootQueryType', // on specifie le type 
    fields: { 
        octocat: {
            type: UserType,
            args: {id: {type: GraphQLID}}, //!\ si notre ID est un string, il mettre un integer (GraphQLInt) et parser
            resolve(parent, args){ // 8. lorsqu'on fera une query (dans GraphiQL), c'est la fonction resolve qui se lance
                return _.find(octocats, {id: args.id});
            }
        },
        watch: {
            type: WatchType,
            args: {id: {type: GraphQLID}},
            resolve(parent, args){
                return _.find(watches, {id: args.id});
            }
        },
        // 9. on crée les listes de nos dummy datas (tableaux)
        octocats: { 
            type: new GraphQLList(UserType),
            resolve(parent, args) {
                return octocats
            }
        },
        watches: {
            type: new GraphQLList(WatchType),
            resolve(parent, args) {
                return watches
            }
        }
    }
})

module.exports = new GraphQLSchema({ // 6. ici on va exporter notre schèma 
    query: RootQuery,    
})   
   

Strepsils - Remplacer les dummy datas par une API.

  • installation et import de 'axios' :
$ npm install axios   
  • mettre en commentaire les dummy datas et dans 'UserType' dans le fields watches
  • faire l'appel d'API dans le 'RootQuery'
    -> 'octocats' pour la liste entière
    -> 'octocat' pour extraire l'item du tableau

Documentation

Schema.js

const graphql = require('graphql'); // 1. on va attribuer à une variable le paquet npm graphql précédemment installé
const _ = require('lodash'); // 7. apres avoir installé lodash 
const axios = require('axios'); // 11. install et import axios

const { GraphQLObjectType, 
       GraphQLString, 
       GraphQLSchema,
       GraphQLInt, // cf. date 
       GraphQLID,
       GraphQLList } = graphql; // 2. ici on va extraire les objets dont on a besoin du package graphql 

// 3. dummy data 
/* const octocats = [
   {id: "22", prenom: "Cedric",nom: "Van Hove", gitHub: "cevaho",linkedIn: "https://www.linkedin.com/in/c%C3%A9dric-van-hove-99250926/",promo: "johnson"},
   {id: "1", prenom: "Maxime", nom: "Broodcoorens", gitHub: "Broodco", linkedIn: "https://www.linkedin.com/in/maxime-broodcoorens-783472168/", promo: "lovelace" },
   {id: "2", prenom: "Emilie", nom: "Bialais", gitHub: "ebialais",linkedIn:"https://www.linkedin.com/in/emilie-bialais-b4b67658/", promo: "lovelace" },
   {id: "3", prenom: "Pierre-Louis", nom: "Picard", gitHub: "Pierre-Louis242",linkedIn:"https://www.linkedin.com/in/pierre-louis-picard-b30993a8/",promo: "lovelace"},
   {id: "4", prenom: "Mathilde",nom: "Baquet", gitHub: "MathildeBa",linkedIn:"https://www.linkedin.com/in/mathilde-baquet",promo: "lovelace"},
   {id: "19", prenom: "Antoine",nom: "Diambu", gitHub: "AntoineDia",linkedIn: "https://www.linkedin.com/in/antoine-diambu-402776178/",promo: "johnson" }
]
*/
/* const watches = [
   {id: "1", octocatId: "3", date: 190319, subject: "Power BI", link: "https://powerbi.microsoft.com/fr-fr/"},
   {id: "2", octocatId: "2", date: 150419, subject: "Black Hole", link:  "https://drive.google.com/open?id=1ZWgEnRzZyCS5RX0AoEPfinbIbmfAQo1Y-JT1E-CyRsU"},
   {id: "3", octocatId: "2", date: 250219, subject: "La minute santé", link: "https://docs.google.com/presentation/d/1bVct12Ttw16G7B-"},
   {id: "4", octocatId: "1", date: 180419, subject: "Back-end: choix d'une technologie", link: "https://slides.com/broodco/deck-1#/"},
   {id: "5", octocatId: "2", date: 20519, subject: "Performance", link: "https://docs.google.com/presentation/d/1g3YF0yUndVZ0n2wGrFxL_85ChPPFjcn0sTLiux2T6aI/edit?usp=sharing"},
   {id: "6", octocatId: "3", date: 40219, subject: "Photo Wake-up 3D, donner vie aux images", link:  "https://github.com/Pierre-louis242/The-Watch-"},
   {id: "7", octocatId: "1", date: 210219, subject: "Raspberry Pi", link: "https://www.raspberrypi.org/"}
] */

// 4. on va créer deja notre 1er type dans le schema (UserType), on donne un nom à notre objet (octocat) + fields avec le type correspondant
const UserType = new GraphQLObjectType ({ 
   name: 'octocat',
   fields: () => ({
       id: {type: GraphQLID},
       prenom: {type: GraphQLString},
       nom: {type: GraphQLString},
       gitHub: {type: GraphQLString},
       linkedIn: {type: GraphQLString},
       promo: {type: GraphQLString},
       /* watches: {
           type: new GraphQLList(WatchType),
           resolve(parent, args){
               return _.filter(watches, { octocatId: parent.id});
           }
       } */

   })
}); //!\ 

// 4.bis : type Watch
const WatchType = new GraphQLObjectType ({
   name: 'watch',
   fields: () => ({
       id: {type: GraphQLID},
       octocatId: { // 10. on va définir le type et matcher via le resolver avec l'octocat correspondant
           type: UserType,
           resolve(parent, args){ // on va chercher l'octocat associé
               // console.log(parent);
               return _.find(octocats, {id: parent.octocatId});
           }
       },
       date: {type: GraphQLInt},
       subject: {type: GraphQLString},
       link: {type: GraphQLString},

   })
}); 



// ROOTQUERY
const RootQuery = new GraphQLObjectType({ // 5. represents all of the possible entry points into the GraphQL API
   name: 'RootQueryType', // on specifie le type 
   fields: { 
       octocat: {
           type: UserType,
           args: {id: {type: GraphQLID}}, //!\ si notre ID est un string, il mettre un integer (GraphQLInt) et parser
           resolve(parent, args){ // 8. lorsqu'on fera une query (dans GraphiQL), c'est la fonction resolve qui se lance
               // #2 - request API & return item
               return axios.get('https://api.sheety.co/97ac06ad-6ce3-4719-ad8d-8ea8711b328b')
                   .then(function (response) {
                       // handle success - on renvoie les datas
                       const resultat = response.data;
                       //let a = resultat.find((item) => item.id === id)
                       return resultat.find((item) => item.id == args.id)
                   })
                   .catch(function (error) {
                       // handle error
                       throw new Error(error.message)
                   })            
           }
       },
       watch: {
           type: WatchType,
           args: {id: {type: GraphQLID}},
           resolve(parent, args){
               return _.find(watches, {id: args.id});
           }
       },
       // 9. on crée les listes de nos dummy datas (tableaux)
       octocats: { 
           type: new GraphQLList(UserType),
           resolve(parent, args) { // 12. on retourne la liste JSON de notre API octocats dorenavant
               // #1 - request API & return liste 
               return axios.get('https://api.sheety.co/97ac06ad-6ce3-4719-ad8d-8ea8711b328b')
                   .then(function (response) {
                       // handle success - on renvoie les datas
                       return response.data
                   })
                   .catch(function (error) {
                       // handle error
                       throw new Error(error.message)
                   })
           }
       },
       watches: {
           type: new GraphQLList(WatchType),
           resolve(parent, args) {
               return watches
           }
       }
   }
})

module.exports = new GraphQLSchema({ // 6. ici on va exporter notre schèma 
   query: RootQuery,    
})

Strep7 - Ajout de REACT.js

ajouter et connection du front end et en ressortir les donées react/graphQL.

  • installer react a la racine (hors du server)
npm install create-react-app -g
  • creer react app a la racine (hors du server)
create-react-app client
  • nettoyer le folder 'src' on garde: 'App.js', 'index.css' et 'index.js' (virer le service provider )
  • creer dans src un folder : 'components'
  • dans le folder creation d'un component (ENFIIIIIN!!!!!) : 'OctocatList.js'
  • mise en place du component 'OctocatList.js'

dans 'App.js'

npm install apollo-boost react-apollo graphql --save
  • on importe ApolloProvider ET ApolloClient
  • set up ApolloClient
  • wrapper le contenu de ApolloProvider
  • Démarer react
    npm start

dans 'octocatList.js'

  • import de {gql} (ATTENTION CA RESSEMBLE A DU JAVASCRIPT MAIS CA N'EN EST PAS!!!!) illusion
  • creer une variable pour nous permettre de faire une query
  • ne pas oublier d'exporter le component avec la fonction grqphql et l'argument qui est le nom de la variable précedemment crééé

retour dans 'server'

  • installer 'cors' qui permet de faire le cross-origin request entre server-client
npm install cors --save

dans 'app.js'

  • importer cors

  • maintenant configuration du lien entre server(GraphQL) et front(React.js) est finie

  • verifier le localhost:3000. Dans la console on peut apercevoir qu'on recoit en effet les data.

Passer a la STEP8 pour le rendu des datas dans le component

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));

components/octocatList.js

import React, { Component } from 'react'
import  { gql } from 'apollo-boost'
import { Query } from 'react-apollo'

// avec les imports gql et graphql, on lie notre requete du component à notre schèma (server)
const getOctocatQuery = gql` 
    {
        octocats {
            id
            nom 
            gitHub
            linkedIn
        }
    }
`

class OctocatList extends Component {
    render() {
        return(
            <Query query={getOctocatQuery}>
                {({ data, loading, error}) => {
                    if (loading) return <p>Loading...</p>
                    if (error) return <p>Error</p>
                    return (                
                    <div>
                        <ul id="octocat-list">
                            {data.octocats && data.octocats.map(octocat => (
                                //assignation dune clef pour chaque octocat
                                <li key={`octocat${octocat.id}`}>
                                    {octocat.id} : {octocat.prenom} {octocat.nom}, GitHub: {octocat.gitHub}
                                </li>
                            ))}
                        </ul>
                    </div>
                    )
                }}
            </Query>
        );
    }
}

// faire attention d'exporter le component 
export default OctocatList;   

App.js

import React from 'react';
import OctocatList from './components/OctocatList';
import { ApolloProvider } from 'react-apollo';

// Depuis Apollo 2.x , il faut importer ces packages supplémentaires 
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { HttpLink } from 'apollo-link-http';

const cache = new InMemoryCache();
const link = new HttpLink({
  uri: 'http://localhost:4044/graphql/'
})


// 1. apollo client setup
const client = new ApolloClient ({
  cache, 
  link,
})

function App() {
  return (
    <ApolloProvider client={client}>
      <div className="App">
        <h1>Liste d'Octocats</h1>
        <OctocatList/>
      </div>
    </ApolloProvider>
  );
}
export default App;

Strep8 - Rendu des datas de l'API dans un component * en live Coding

  • creer une methode (dans le style de render) qui recupère les datas issues de la requête faite a l'etape d'avant, displayOctocats(){}.
  • inporter Query de Appolo
  • extraire du tableau chaque Octocats en précisent les champs utiles
    (Documentation de apolloClient : https://www.apollographql.com/docs/react/essentials/queries/)
  • assigner une clef pour chaque Octocat

components/octocatList.js

import React, { Component } from 'react'
import  { gql } from 'apollo-boost'
import { Query } from 'react-apollo'

// avec les imports gql et graphql, on lie notre requete du component à notre schèma (server)
const getOctocatQuery = gql`{
        octocats {
            id
            nom 
            prenom
            gitHub
        }
    }
    `

class OctocatList extends Component {
/*     displayOctocats(){ // methode de rendu 
        var data = this.props.data;
        if(data.loading){
            return (<div>Loading octocats...</div>);
        } else {
            return data.octocats.map(octocat => {
                return(
                    <h1> key={octocat.id}>{octocat.nom} {octocat.prenom}</h1>,
                    <p key={octocat.id}>{octocat.linkedIn}</p>
                );
            })
        }
    } */
    render() {
        return(
            <Query query={getOctocatQuery}>
                {({ data, loading, error}) => {
                    if (loading) return <p>Loading...</p>
                    if (error) return <p>Error</p>
                    return (                
                    <div>
                        <ul id="octocat-list">
                            {data.octocats && data.octocats.map(octocat => (
                                //assignation dune clef pour chaque octocat
                                <li key={`octocat${octocat.id}`}>
                                    {octocat.id} : {octocat.prenom} {octocat.nom}, GitHub: {octocat.gitHub}
                                </li>
                            ))}
                        </ul>
                    </div>
                    )
                }}
            </Query>
        );
    }
}

// faire attention d'exporter le component 
export default OctocatList

About

Connecter une API à une app React.js, via GraphQL (schéma et environnement)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published