Úvod do GraphQL: jak to funguje a jak je používat

Foto Matt Duncan na Unsplash

GraphQL je jazykem dotazů pro API. Ukazuje, jaké jsou různé typy dat poskytovaných serverem a poté si klient může vybrat přesně to, co chce.

Také v GraphQL můžete získat více serverových prostředků na jedno volání namísto více volání REST API.

Úplný seznam výhod naleznete na adrese https://graphql.org/.

Jde o to, dokud neuvidíte GraphQL v akci, je těžké pochopit výhody. Začněme tedy s používáním GraphQL.

V tomto článku budeme používat GraphQL spolu s NodeJS.

Předpoklady

NodeJS nainstalujte zde: https://nodejs.org/en/.

Jak používat GraphQL s NodeJs

GraphQL lze použít s více jazyky. Zde se zaměříme na to, jak můžeme používat GraphQL s JavaScript pomocí NodeJS.

Vytvořte složku nazvanou graphql-with-nodejs. Jděte do složky projektu a spusťte npm init a vytvořte projekt NodeJS. Příkaz k tomu je uveden níže.

cd graphql-with-nodejs
npm init

Nainstalujte závislosti

Nainstalujte Express pomocí následujícího příkazu:

npm install express

Nainstalujte GraphQL pomocí následujícího příkazu. Budeme instalovat GraphQL a GraphQL pro Express.

npm install express-graphql graphql

Kód NodeJS

V projektu vytvořte soubor s názvem server.js a zkopírujte do něj následující kód:

const express = vyžádat ('express');
const port = 5000;
const app = express ();

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

app.listen (port);
console.log (`Server spuštěn na localhost: $ {port}`);

Výše uvedený kód má jediný koncový bod HTTP GET nazvaný / ahoj.

Koncový bod je vytvořen pomocí Express.

Nyní upravme tento kód tak, aby umožňoval GraphQL.

Povolení GraphQL v kódu

GraphQL bude mít jediný koncový bod URL nazvaný / graphql, který bude zpracovávat všechny požadavky.

Zkopírujte následující kód do souboru server.js:

// získejte všechny potřebné knihovny
const express = vyžádat ('express');
const graphqlHTTP = vyžadovat ('express-graphql');
const {GraphQLSchema} = vyžadovat ('graphql');

const {queryType} = vyžadovat ('./ query.js');

// nastavení čísla portu a aplikace pro expres
const port = 5000;
const app = express ();

 // Definujte schéma
const schema = new GraphQLSchema ({query: queryType});

// Nastavení nodejs GraphQL serveru
app.use ('/ graphql', graphqlHTTP ({
    schéma: schéma,
    graphiql: true,
}));

app.listen (port);
console.log (`GraphQL Server spuštěný na localhost: $ {port}`);

Pojďme nyní projít tento kód.

graphqlHTTP nám umožňuje nastavit server GraphQL na adrese / graphql url. Umí vyřídit požadavek, který přichází.

Toto nastavení se provádí v následujících řádcích kódu:

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

Nyní se podívejme na parametry uvnitř graphqlHTTP.

graphiql

graphiql je webové uživatelské rozhraní, pomocí kterého můžete testovat koncové body GraphQL. Toto nastavíme na true, takže je snazší otestovat různé GraphQL koncové body, které vytváříme.

schéma

GraphQL má pouze jeden externí koncový bod / graphql. Tento koncový bod může mít několik dalších koncových bodů, které dělají různé věci. Tyto koncové body budou specifikovány ve schématu.

Schéma by dělalo věci jako:

  • Určete koncové body
  • Označte vstupní a výstupní pole pro koncový bod
  • Uveďte, jaká akce by měla být provedena, když je zasažen koncový bod atd.

Schéma je v kódu definována takto:

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

Schéma může obsahovat typy dotazů i mutací. Tento článek se zaměří pouze na typ dotazu.

dotaz

Ve schématu můžete vidět, že dotaz byl nastaven na queryType.

Importujeme queryType ze souboru query.js pomocí následujícího příkazu:

const {queryType} = vyžadovat ('./ query.js');

query.js je vlastní soubor, který brzy vytvoříme.

dotaz je místo, kde ve schématu určíme koncové body jen pro čtení.

Vytvořte v projektu soubor nazvaný query.js a zkopírujte do něj následující kód.

const {GraphQLObjectType,
    GraphQLString
} = vyžadovat ('graphql');


// Definujte dotaz
const queryType = new GraphQLObjectType ({
    jméno: 'Query',
    pole: {
        Ahoj: {
            typ: GraphQLString,

            vyřešit: function () {
                návrat "Hello World";
            }
        }
    }
});

export.queryType = queryType;

dotaz Vysvětleno

queryType je vytvořen jako GraphQLObjectType a má jméno Query.

pole určují různé koncové body.

Takže zde přidáváme jeden koncový bod zvaný ahoj.

ahoj má typ GraphQLString, což znamená, že tento koncový bod má návratový typ String. Typem je GraphQLString místo String, protože se jedná o schéma GraphQL. Přímé používání řetězce tedy nebude fungovat.

rozlišovací funkce označuje akci, která se má provést při vyvolání koncového bodu. Zde je akce vrátit řetězec „Ahoj svět“.

Nakonec exportujeme typ dotazu pomocí vývozu.queryType = queryType. Toto je zajistit, abychom jej mohli importovat do server.js.

Spuštění aplikace

Spusťte aplikaci pomocí následujícího příkazu:

uzel server.js

Aplikace běží na localhost: 5000 / graphql.

Aplikaci můžete vyzkoušet na localhost: 5000 / graphql.

Tato adresa URL spouští webové uživatelské rozhraní Graphiql, jak je znázorněno na níže uvedené obrazovce.

Vstup je uveden vlevo a výstup je zobrazen vpravo.

Zadejte následující vstup

{
  Ahoj
}

Tím získáte následující výstup

{
  "data": {
    "ahoj": "Ahoj svět"
  }
}

Gratulujeme

Vytvořili jste svůj první koncový bod GraphQL.

Přidání dalších koncových bodů

Vytvoříme 2 nové koncové body:

  • movie: Tento koncový bod vrátí film s ID filmu
  • director: Tento koncový bod vrátí režisérovi dané ID režiséra. Vrátí také všechny filmy režírované tímto režisérem.

Přidávání dat

Obvykle aplikace načte data z databáze. Ale v tomto tutoriálu budeme pro jednoduchost tvrdě kódovat data v samotném kódu.

Vytvořte soubor s názvem data.js a přidejte následující kód.

// Vytvářejte některá data pro filmy a režiséry
nechat filmy = [{
    id: 1,
    název: "Movie 1",
    rok: 2018,
    režisér: 1
},
{
    id: 2,
    název: "Movie 2",
    rok: 2017,
    režisér: 1
},
{
    id: 3,
    název: "Movie 3",
    rok: 2016,
    režisér: 3
}
];

nechat režiséry = [{
    id: 1,
    jméno: "Director 1",
    věk: 20 let
},
{
    id: 2,
    jméno: "Director 2",
    věk: 30 let
},
{
    id: 3,
    jméno: "Director 3",
    věk: 40 let
}
];

export.movies = filmy;
export.directors = režiséři;

Tento soubor obsahuje data filmů a režisérů. Data v tomto souboru použijeme pro naše koncové body.

Přidání koncového bodu filmu do dotazu

Nové koncové body budou přidány do queryType v souboru query.js.

Kód koncového bodu filmu je uveden níže:

film: {
            typ: movieType,
            args: {
                id: {type: GraphQLInt}
            },
            vyřešit: function (source, args) {
                return _.find (filmy, {id: args.id});
            }
        }

Návratový typ tohoto koncového bodu je movieType, který bude brzy definován.

Parametr args se používá k označení vstupu do koncového bodu filmu. Vstupem do tohoto koncového bodu je id typu GraphQLInt.

funkce Resolution vrací film odpovídající id, ze seznamu filmů. find je funkce z knihovny Lodash, která slouží k nalezení prvku v seznamu.

Kompletní kód pro dotaz.js je uveden níže:

const {GraphQLObjectType,
    GraphQLString,
    GraphQLInt
} = vyžadovat ('graphql');
const _ = vyžadovat ('lodash');

const {movieType} = vyžadovat ('./ types.js');
nechat {movies} = vyžadovat ('./ data.js');


// Definujte dotaz
const queryType = new GraphQLObjectType ({
    jméno: 'Query',
    pole: {
        Ahoj: {
            typ: GraphQLString,

            vyřešit: function () {
                návrat "Hello World";
            }
        },

        film: {
            typ: movieType,
            args: {
                id: {type: GraphQLInt}
            },
            vyřešit: function (source, args) {
                return _.find (filmy, {id: args.id});
            }
        }
    }
});

export.queryType = queryType;

Z výše uvedeného kódu vidíme, že movieType je ve skutečnosti definován v typech.js.

Přidání uživatelského typu movieType

Vytvořte soubor s názvem types.js.

Přidejte následující kód do types.js

const {
    GraphQLObjectType,
    GraphQLID,
    GraphQLString,
    GraphQLInt
} = vyžadovat ('graphql');

// Definujte typ filmu
movieType = new GraphQLObjectType ({
    jméno: 'Movie',
    pole: {
        id: {type: GraphQLID},
        name: {type: GraphQLString},
        rok: {type: GraphQLInt},
        directorId: {type: GraphQLID}

    }
});

export.movieType = movieType;

Je vidět, že movieType je vytvořen jako GraphQLObjectType.

Má 4 pole: id, jméno, rok a režisér. Typy pro každé z těchto polí jsou také specifikovány při jejich přidávání.

Tato pole pocházejí přímo z dat. V tomto případě to bude ze seznamu filmů.

Přidání dotazu a typu koncového bodu režiséra

Jako film lze přidat i koncový bod režiséra.

V query.js lze koncový bod ředitele přidat takto:

režisér: {
            typ: directorType,
            args: {
                id: {type: GraphQLInt}
            },
            vyřešit: function (source, args) {
                return _.find (ředitelé, {id: args.id});
            }
        }

directorType může být přidán takto v typech.js:

// Definujte typ ředitele
directorType = new GraphQLObjectType ({
    jméno: 'Director',
    pole: {
        id: {type: GraphQLID},
        name: {type: GraphQLString},
        age: {type: GraphQLInt},
        filmy: {
            typ: nový GraphQLList (movieType),
            vyřešit (zdroj, args) {
                return _.filter (filmy, {directorId: source.id});
            }

        }

    }
});

Počkej chvíli. The directorType se mírně liší od movieType. Proč je to?

Proč existuje funkce Resolution uvnitř DirectorType? Dříve jsme viděli, že rozlišovací funkce byly přítomny pouze v dotazu…

Zvláštní povaha režiséraType

Když se volá koncový bod režiséra, musíme vrátit podrobnosti o režisérovi, stejně jako všechny filmy, které režisér režíroval.

První 3 pole id, jméno, věk v DirectorType jsou přímočará a pocházejí přímo z dat (seznam ředitelů).

Čtvrté pole, filmy, musí obsahovat seznam filmů od tohoto režiséra.

Z tohoto důvodu uvádíme, že pole typu filmů je GraphQLList typu movieType (Seznam filmů).

Ale jak přesně najdeme všechny filmy režiséra tohoto režiséra?

Za tímto účelem máme uvnitř pole filmů funkci rozlišení. Vstupy do této rozlišovací funkce jsou zdroj a args.

zdroj bude mít podrobnosti nadřazeného objektu.

Řekněme, že pole id = 1, name = „Random“ a age = 20 pro režiséra. Pak source.id = 1, source.name = „Random“ a source.age = 20

V tomto příkladu tedy funkce řešení najde všechny filmy, ve kterých se režisér shoduje s ID požadovaného režiséra.

Kód

Celý kód pro tuto aplikaci je k dispozici v tomto repozitáři GitHub

Testování aplikace

Nyní vyzkoušejte aplikaci pro různé scénáře.

Spusťte aplikaci pomocí uzlu server.js.

Přejděte na localhost: 5000 / graphql a zkuste následující vstupy.

film

Vstup:

{
  film (id: 1) {
    název
  }
}

Výstup:

{
  "data": {
    "movie": {
      "name": "Movie 1"
    }
  }
}

Z výše uvedeného vidíme, že klient může požadovat přesně to, co chce, a GraphQL zajistí, že budou posílány pouze tyto parametry. Zde je vyžadováno pouze pole s názvem a pouze to je server odesláno zpět.

Ve filmu (id: 1) je id vstupní parametr. Žádáme server, aby poslal zpět film, který má id 1.

Vstup:

{
  film (id: 3) {
    název
    id
    rok
  }
}

Výstup:

{
  "data": {
    "movie": {
      "name": "Movie 3",
      "id": "3",
      "year": 2016
    }
  }
}

Ve výše uvedeném příkladu jsou požadována pole id, rok a rok. Server tedy odešle všechna tato pole zpět.

ředitel

Vstup:

{
  režisér (id: 1) {
    název
    id,
    stáří
  }
}

Výstup:

{
  "data": {
    "director": {
      "name": "Director 1",
      "id": "1",
      "věk": 20
    }
  }
}

Vstup:

{
  režisér (id: 1) {
    název
    id,
    stáří,
    filmy{
      název,
      rok
    }
  }
}

Výstup:

{
  "data": {
    "director": {
      "name": "Director 1",
      "id": "1",
      "věk": 20,
      "filmy": [
        {
          "name": "Movie 1",
          "rok": 2018
        },
        {
          "name": "Movie 2",
          "year": 2017
        }
      ]
    }
  }
}

Ve výše uvedeném příkladu vidíme sílu GraphQL. Označujeme, že chceme režiséra s ID 1. Také označujeme, že chceme všechny filmy od tohoto režiséra. Pole režiséra i filmu jsou přizpůsobitelná a klient si může vyžádat přesně to, co chce.

Podobně to lze rozšířit na další pole a typy. Mohli bychom například spustit dotaz jako Najít režiséra s id 1. Pro tohoto režiséra najít všechny filmy. Pro každý film najděte herce. Pro každého herce získejte 5 nejlepších hodnocených filmů atd. Pro tento dotaz musíme určit vztah mezi typy. Jakmile to uděláme, může klient požádat o jakýkoli vztah, který chce.

Gratulujeme

Nyní znáte základní pojmy GraphQL.

V dokumentaci se můžete dozvědět více o GraphQL

O autorovi

Miluji technologii a sleduji pokrok v oboru. Také rád pomáhám ostatním se svými technologickými znalostmi.

Neváhejte a spojte se mnou na mém účtu LinkedIn https://www.linkedin.com/in/aditya1811/

Můžete mě také sledovat na Twitteru https://twitter.com/adityasridhar18

Můj web: https://adityasridhar.com/

Původně zveřejněno na adrese adityasridhar.com.