Bevezetés a GraphQL-hez: hogyan működik és hogyan kell használni

Fotó: Matt Duncan az Unsplash-en

A GraphQL az API-k lekérdezési nyelve. Megmutatja, hogy milyen különféle adatokat szolgáltat a szerver, majd az ügyfél pontosan kiválaszthatja, amit akar.

A GraphQL-ben is több szerver erőforrást szerezhet egyetlen hívásban, ahelyett, hogy több REST API-hívást kezdene.

Nézze meg a https://graphql.org/ oldalt az előnyök teljes listájáért.

A helyzet addig, amíg nem látja a GraphQL működését, nehéz megérteni az előnyöket. Tehát kezdjük el a GraphQL használatával.

Ebben a cikkben a GraphQL-t és a NodeJS-t fogjuk használni.

Előfeltétele

Telepítse a NodeJS-t innen: https://nodejs.org/en/.

Hogyan kell használni a GraphQL-t a NodeJ-kkel

A GraphQL több nyelven használható. Itt arra összpontosítunk, hogyan tudjuk használni a GraphQL-t a JavaScript használatával a NodeJS segítségével.

Hozzon létre egy mappát, amelyet graphql-with-nodejs-nak hívnak. Menjen be a projekt mappába, és futtassa az npm init programot a NodeJS projekt létrehozásához. Erre a parancs az alábbiakban található.

cd graphql-with-nodejs
npm init

Telepítse a függőségeket

Telepítse az Express szolgáltatást a következő paranccsal:

npm install express

Telepítse a GraphQL-t a következő paranccsal. Telepítjük a GraphQL és a GraphQL for Express rendszert.

npm install express-graphql graphql

NodeJS kód

Hozzon létre egy server.js nevű fájlt a projektben, és másolja be a következő kódot:

const express = igényel ('express');
const port = 5000;
const app = express ();

app.get ('/ hello', (req, res) => {
    res.send ( "helló");
   }
);

app.listen (port);
console.log (`Szerver fut helyi kiszolgálón: $ {port} ');

A fenti kódnak egyetlen HTTP GET végpontja van, azaz hello.

A végpont az Express használatával jön létre.

Most módosítsuk ezt a kódot a GraphQL engedélyezéséhez.

A GraphQL engedélyezése a kódban

A GraphQL egyetlen URL végponttal rendelkezik, az úgynevezett / graphql néven, amely minden kérést kezelni fog.

Másolja a következő kódot a server.js fájlba:

// az összes szükséges könyvtár beolvasása
const express = igényel ('express');
const graphqlHTTP = igény ('express-graphql');
const {GraphQLSchema} = igényelni ('graphql');

const {queryType} = igényelni ('./ query.js');

// a portszám és az expressz alkalmazás beállítása
const port = 5000;
const app = express ();

 // Határozza meg a sémát
const schema = új GraphQLSchema ({query: queryType});

// Telepítse a nodejs GraphQL szervert
app.use ('/ graphql', graphqlHTTP ({
    séma: séma,
    graphiql: igaz,
}));

app.listen (port);
console.log (`GraphQL Server fut a localhoston: $ {port}`);

Menjünk át most ezen a kódon.

A graphqlHTTP lehetővé teszi a GraphQL szerver beállítását a / graphql url címen. Tudja, hogyan kell kezelni a beérkező kérelmet.

Ez a beállítás a következő kódsorokban történik:

app.use ('/ graphql', graphqlHTTP ({
    séma: séma,
    graphiql: igaz,
}));

Most hadd vizsgáljuk meg a graphqlHTTP paramétereit.

graphiql

A graphiql egy webes felhasználói felület, amellyel kipróbálhatja a GraphQL végpontokat. Ezt igazra állítjuk, hogy könnyebb kipróbálni a létrehozott különféle GraphQL végpontokat.

séma

A GraphQL-nek csak egy külső végpontja / graphql van. Ennek a végpontnak több más végpontja is lehet, amelyek különféle dolgokat csinálnak. Ezeket a végpontokat a séma határozza meg.

A séma a következőket teheti:

  • Adja meg a végpontokat
  • Jelölje meg a végpont bemeneti és kimeneti mezőit
  • Jelölje meg, hogy mit kell tenni egy végpont elérésekor és így tovább.

A séma a következőképpen van meghatározva a kódban:

const schema = új GraphQLSchema ({query: queryType});

A séma tartalmazhat lekérdezést és mutációs típusokat. Ez a cikk csak a lekérdezés típusára összpontosít.

lekérdezés

A sémában láthatja, hogy a lekérdezés a queryType-re van állítva.

A queryType fájlt a query.js fájlból a következő paranccsal importáljuk:

const {queryType} = igényelni ('./ query.js');

A query.js egy egyéni fájl, amelyet hamarosan létrehozunk.

A lekérdezés az, ahol meghatározzuk az írásvédett végpontokat egy sémában.

Hozzon létre egy query.js néven létrehozott fájlt a projektben, és másolja be a következő kódot.

const {GraphQLObjectType,
    GraphQLString
} = igényelni ('graphql');


// Adja meg a lekérdezést
const queryType = új GraphQLObjectType ({
    név: 'Query',
    mezők: {
        Szia: {
            típus: GraphQLString,

            feloldás: function () {
                vissza a "Hello World";
            }
        }
    }
});

export.queryType = queryType;

lekérdezés magyarázva

A queryType GraphQLObjectType fájlként jön létre, és Query névvel rendelkezik.

a mezőkben meghatározzuk a különböző végpontokat.

Tehát itt hozzáadunk egy hello nevű végpontot.

A hello egy olyan típusú GraphQLString, amely azt jelenti, hogy ennek a végpontnak egy visszatérési karakterlánca van. A típust a string helyett GraphQLString használja, mivel ez egy GraphQL séma. Tehát a String közvetlenül nem fog működni.

feloldási funkció jelzi a végpont meghívásakor végrehajtandó műveletet. Itt az a lépés, hogy visszatérjen egy "Hello World" karakterlánc.

Végül exportáljuk a lekérdezéstípust az export.queryType = queryType használatával. Ez biztosítja, hogy be tudjuk importálni a server.js fájlba.

Az alkalmazás futtatása

Futtassa az alkalmazást a következő paranccsal:

node server.js

Az alkalmazás a localhoston fut: 5000 / graphql.

Az alkalmazást kipróbálhatja a localhost webhelyen: 5000 / graphql.

Ez az URL az alábbi képen látható módon futtatja a Graphiql webes felhasználói felületet.

A bemenetet a bal oldalon adjuk meg, a kimenetet pedig a jobb oldalon.

Adja meg a következő bemenetet

{
  Szia
}

Ez a következő eredményt adja

{
  "adatok": {
    "hello": "Hello World"
  }
}

Gratulálok

Készítette az első GraphQL végpontját.

További végpontok hozzáadása

2 új végpontot hozunk létre:

  • film: Ez a végpont filmet ad vissza, megadva a film azonosítóját
  • rendező: Ez a végpont a rendező azonosítójával megadott rendezőt ad vissza. Visszaadja az összes rendező filmjét is.

Adatok hozzáadása

Általában egy alkalmazás adatot vesz be egy adatbázisból. De ehhez az oktatóanyaghoz az egyszerűség kedvéért keményen kódoljuk az adatokat a kódban.

Hozzon létre egy data.js nevű fájlt, és adja hozzá a következő kódot.

// Néhány adat a filmekhez és a rendezőkhöz
hagyja, hogy a filmek = [{
    id: 1,
    név: "1. film",
    év: 2018,
    DirectorId: 1
},
{
    id: 2,
    név: "2. film",
    év: 2017,
    DirectorId: 1
},
{
    id: 3,
    név: "3. film",
    év: 2016,
    rendezőId: 3
}
];

hadd rendezők = [{
    id: 1,
    név: "1. igazgató",
    életkor: 20
},
{
    id: 2,
    név: "2. igazgató",
    életkor: 30 év
},
{
    id: 3,
    név: "3. igazgató",
    életkor: 40 év
}
];

export.movies = filmek;
export.directors = igazgatók;

Ez a fájl tartalmazza a filmeket és a rendezők adatait. A fájlban szereplő adatokat a végpontjainkra fogjuk használni.

A film végpontjának hozzáadása a lekérdezéshez

Az új végpontok hozzáadódnak a queryType fájlhoz a query.js fájlban.

A film végpontjának kódja az alábbiakban látható:

film: {
            típus: movieType,
            args: {
                id: {type: GraphQLInt}
            },
            feloldás: függvény (forrás, args) {
                return _.find (filmek, {id: args.id});
            }
        }

Ennek a végpontnak a visszatérési típusa a movieType, amelyet hamarosan meghatározunk.

Az args paraméter a bemenet jelzésére szolgál a film végpontjára. Ennek a végpontnak a bemenete azonosítója, amely GraphQLInt típusú.

A feloldás funkció az azonosítónak megfelelő filmet adja vissza a filmlistából. a keresés a lodash könyvtár függvénye, amelyet egy elem elem megkeresésére használnak a listában.

Az alábbiakban látható a query.js teljes kódja:

const {GraphQLObjectType,
    GraphQLString,
    GraphQLInt
} = igényelni ('graphql');
const _ = igényelni ('lodash');

const {movieType} = igényelni ('./ type.js');
hagyja, hogy a {filmek} = megköveteljék ('./ data.js');


// Adja meg a lekérdezést
const queryType = új GraphQLObjectType ({
    név: 'Query',
    mezők: {
        Szia: {
            típus: GraphQLString,

            feloldás: function () {
                vissza a "Hello World";
            }
        },

        film: {
            típus: movieType,
            args: {
                id: {type: GraphQLInt}
            },
            feloldás: függvény (forrás, args) {
                return _.find (filmek, {id: args.id});
            }
        }
    }
});

export.queryType = queryType;

A fenti kódból láthatjuk, hogy a movieType valójában a tips.js fájlban van meghatározva.

A filmType egyedi típusának hozzáadása

Hozzon létre egy type.js nevű fájlt.

Adja hozzá a következő kódot a type.js fájlhoz

const {
    GraphQLObjectType,
    GraphQLID,
    GraphQLString,
    GraphQLInt
} = igényelni ('graphql');

// A film típusának meghatározása
movieType = új GraphQLObjectType ({
    név: „film”,
    mezők: {
        id: {type: GraphQLID},
        név: {típus: GraphQLString},
        év: {type: GraphQLInt},
        DirectorId: {type: GraphQLID}

    }
});

export.movieType = movieType;

Látható, hogy a movieType GraphQLObjectType formátumban van létrehozva.

4 mezővel rendelkezik: azonosító, név, év és DirectorId. A mezők típusait a hozzáadásuk során is meghatározták.

Ezek a mezők közvetlenül az adatokból származnak. Ebben az esetben a filmek listájából származik.

A lekérdezés és a típus hozzáadása az irányító végponthoz

Mint a film, akár a rendezői végpont is hozzáadható.

A query.js fájlban az irányító végpont a következőképpen adható hozzá:

rendező: {
            típus: DirectorType,
            args: {
                id: {type: GraphQLInt}
            },
            feloldás: függvény (forrás, args) {
                return _.find (rendezők, {id: args.id});
            }
        }

A directorType a következőképpen adható hozzá a tips.js-ben:

// Adja meg a rendező típusát
DirectorType = új GraphQLObjectType ({
    név: „rendező”,
    mezők: {
        id: {type: GraphQLID},
        név: {típus: GraphQLString},
        életkor: {type: GraphQLInt},
        filmek: {
            típus: új GraphQLList (movieType),
            feloldás (forrás, kérdések) {
                return _.filter (filmek, {directorId: source.id});
            }

        }

    }
});

Várj egy percet. A directorType kissé eltér a filmType-től. Miért ez?

Miért van feloldási funkció a DirectorType-ben? Korábban láttuk, hogy a feloldási funkciók csak a lekérdezésben vannak jelen ...

A DirectorType különleges jellege

Amikor a rendező végpontját hívják, vissza kell adnunk a rendező adatait, valamint az összes filmet, amelyet a rendező rendezett.

Az első 3 mező, azonosító, név, életkor a DirectorType-ben egyértelmű és közvetlenül az adatokból származik (igazgatók listája).

A negyedik mezőnek, a filmeknek tartalmazniuk kell a rendező filmjeinek listáját.

Ehhez megemlítjük, hogy a filmek mezőjének típusa a filmType (Filmek listája) GraphQLList listája.

De pontosan hogyan fogjuk megtalálni az összes rendező filmjét?

Ehhez van egy feloldó funkció a filmek területén. A feloldási funkció bemenetei a forrás és az arg.

A forrás tartalmazza a szülőobjektum részleteit.

Tegyük fel, hogy az id = 1, name = „Random” és age = 20 mezők egy rendezőnél. Majd source.id = 1, source.name = “Random” és source.age = 20

Tehát ebben a példában a feloldási függvény megtudja azokat a filmeket, amelyekben a directorId megegyezik a szükséges rendező azonosítójával.

Kód

Az alkalmazás teljes kódja elérhető a GitHub repóban

Az alkalmazás tesztelése

Most teszteljük az alkalmazást különböző forgatókönyvekre.

Futtassa az alkalmazást a node server.js segítségével.

Lépjen a localhost oldalra: 5000 / graphql, és próbálja ki a következő bemeneteket.

film

Bemenet:

{
  film (id: 1) {
    név
  }
}

Kimenet:

{
  "adatok": {
    "film": {
      "név": "1. film"
    }
  }
}

A fentiekből láthatjuk, hogy az ügyfél pontosan azt kérheti, amit akar, és a GraphQL biztosítja, hogy csak ezeket a paramétereket küldjék vissza. Itt csak a névmezőt kell kérni, és csak azt a szerver küldi vissza.

Filmben (id: 1) az id a bemeneti paraméter. Arra kérjük a szervert, hogy küldje vissza az 1 azonosítójú filmet.

Bemenet:

{
  film (id: 3) {
    név
    id
    év
  }
}

Kimenet:

{
  "adatok": {
    "film": {
      "név": "3. film",
      "id": "3",
      "év": 2016
    }
  }
}

A fenti példában a név, az id és az év mezőket kell megadni. Tehát a szerver küldi vissza ezeket a mezőket.

rendező

Bemenet:

{
  rendező (azonosító: 1) {
    név
    id,
    kor
  }
}

Kimenet:

{
  "adatok": {
    "rendező": {
      "név": "igazgató 1",
      "id": "1",
      "életkor": 20
    }
  }
}

Bemenet:

{
  rendező (azonosító: 1) {
    név
    id,
    kor,
    filmek {
      név,
      év
    }
  }
}

Kimenet:

{
  "adatok": {
    "rendező": {
      "név": "igazgató 1",
      "id": "1",
      "életkor": 20,
      "filmek": [
        {
          "név": "1. film",
          "év": 2018
        },
        {
          "név": "2. film",
          "év": 2017
        }
      ]
    }
  }
}

A fenti példában a GraphQL erejét látjuk. Jelöljük, hogy egy első azonosítójú rendezőt akarunk. Azt is jelezzük, hogy az összes filmet szeretnénk e rendezőtől. Mind a rendező, mind a film mező testreszabható, és az ügyfél pontosan azt kérheti, amit akar.

Hasonlóképpen, ez kiterjeszthető más mezőkre és típusokra is. Például futtathatunk olyan lekérdezést, mint az 1. azonosítóval rendelkező rendező keresése. Ehhez a rendezőhez keresse meg az összes filmet. Minden filmhez keresse meg a színészeket. Mindegyik színész számára szerezze be az öt legjobb filmet és így tovább. Ennek a lekérdezésnek meg kell határoznia a típusok közötti kapcsolatot. Miután ezt megtettük, az ügyfél bármilyen kapcsolatot lekérdezhet, amelyet szeretne.

Gratulálok

Most már ismeri a GraphQL alapelveit.

Nézze meg a dokumentációt, hogy többet tudjon meg a GraphQL-ről

A szerzőről

Szeretem a technológiát, és követem az előrelépéseket ezen a területen. Szeretek másoknak is segíteni a technológiai ismereteimmel.

Ne habozzon kapcsolatba lépni velem a LinkedIn-fiókomon: https://www.linkedin.com/in/aditya1811/

A Twitteren is követhetsz engem a https://twitter.com/adityasridhar18 oldalon

Saját webhelyem: https://adityasridhar.com/

Eredetileg az adityasridhar.com oldalon tették közzé.