Уводзіны ў GraphQL: як ён працуе і як ім карыстацца

Фота Мэта Данкана на Unsplash

GraphQL - мова запытаў для API. Адлюстроўваюцца розныя тыпы дадзеных, якія прадастаўляюцца серверам, і кліент можа выбраць менавіта тое, што хоча.

У GraphQL вы таксама можаце атрымаць некалькі рэсурсаў сервера за адзін званок замест таго, каб рабіць некалькі выклікаў REST API.

З поўным спісам ільгот можна азнаёміцца ​​на https://graphql.org/.

Уся справа ў тым, што пакуль вы не ўбачыце GraphQL у дзеянні, цяжка зразумець перавагі. Такім чынам, пачнем выкарыстоўваць GraphQL.

У гэтым артыкуле мы будзем выкарыстоўваць GraphQL разам з NodeJS.

Патрабаванні

Усталюйце NodeJS адсюль: https://nodejs.org/en/.

Як выкарыстоўваць GraphQL з NodeJs

GraphQL можна выкарыстоўваць на некалькіх мовах. Тут мы спынімся на тым, як мы можам выкарыстоўваць GraphQL з JavaScript з дапамогай NodeJS.

Стварыце тэчку пад назвай graphql-with-nodejs. Перайдзіце ў тэчку праекта і запусціце npm init, каб стварыць праект NodeJS. Каманда для гэтага прыведзена ніжэй.

cd graphql-with-nodejs npm init

Усталюйце залежнасці

Усталюйце Express з дапамогай наступнай каманды:

npm ўсталяваць Express

Усталюйце GraphQL з дапамогай наступнай каманды. Мы ўсталюем GraphQL і GraphQL для Express.

npm ўсталяваць express-graphql graphql

Код NodeJS

Стварыце ў праекце файл з назвай server.js і скапіруйце ў яго наступны код:

const express = патрабаваць ('express'); const порт = 5000; const app = express (); app.get ('/ hello', (req, res) => {res.send ("прывітанне");}); app.listen (порт); console.log (`Сервер працуе на localhost: $ {port}`);

Код вышэй мае адзіную канчатковую кропку HTTP GET пад назвай / прывітанне.

Канчатковая кропка ствараецца з дапамогай Express.

Зараз давайце зменім гэты код, каб уключыць GraphQL.

Уключыць GraphQL у кодзе

GraphQL мае адзіную канчатковую кропку URL пад назвай / graphql, якая апрацоўвае ўсе запыты.

Скапіруйце наступны код у server.js:

// атрымаць усе неабходныя бібліятэкі const express = requ ('express'); const graphqlHTTP = requ ('express-graphql'); const {GraphQLSchema} = патрабаваць ('graphql'); const {queryType} = патрабаваць ('./ query.js'); // наладзіць нумар порта і порт экспрэс-прыкладання const = 5000; const app = express (); // Вызначце схему const schema = new GraphQLSchema ({query: queryType}); // Наладзіць сервер GraphQL вузла app.use ('/ graphql', graphqlHTTP ({схема: схема, graphiql: true,})); app.listen (порт); console.log (`GraphQL Server працуе ў localhost: $ {port}`);

Зараз перагледзім гэты код.

З дапамогай graphqlHTTP мы можам наладзіць сервер GraphQL пад URL / graphql. Ён ведае, як змагацца з які паступае запытам.

Гэтая ўстаноўка ажыццяўляецца ў наступных радках кода:

app.use ('/ graphql', graphqlHTTP ({схема: схема, graphiql: true,}));

Зараз давайце вывучым параметры ў graphqlHTTP.

graphiql

graphiql - гэта вэб-карыстацкі інтэрфейс, які можна выкарыстоўваць для праверкі канчатковых кропак GraphQL. Мы ўсталёўваем гэта як сапраўднае, каб зрабіць яго больш лёгкім для праверкі розных канчатковых пунктаў GraphQL, якія мы стварылі.

Схема

GraphQL мае толькі адну знешнюю канчатковую кропку / graphql. Гэтая канчатковая кропка можа мець некалькі іншых канчатковых кропак, якія выконваюць розныя заданні. Гэтыя канчатковыя кропкі будуць пазначаны на схеме.

Схема будзе рабіць наступныя рэчы:

  • Укажыце канчатковыя кропкі
  • Увядзіце палі ўводу і вываду для канчатковай кропкі
  • Пазначце, якія дзеянні трэба зрабіць, калі будзе дасягнута канчатковая кропка і гэтак далей.

Схема вызначаецца ў кодзе наступным чынам:

const схема = новая GraphQLSchema ({запыт: queryType});

Схема можа ўтрымліваць як тыпы запытаў, так і мутацыі. Гэты артыкул прысвечана толькі тыпу запыту.

Запыт

На схеме вы бачыце, што запыт быў усталяваны ў queryType.

Мы імпартуем queryType з файла query.js наступнай камандай:

const {queryType} = патрабаваць ('./ query.js');

query.js - гэта ўласны файл, які мы хутка створым.

У запыце мы паказваем канчатковыя кропкі, якія толькі для чытання, у схеме.

Стварыце ў праекце файл з імем query.js і скапіруйце ў яго наступны код.

const {GraphQLObjectType, GraphQLString} = патрабуе ('graphql'); // Вызначце запыт const queryType = new GraphQLObjectType ({name: 'Query', поля: {Hello: {Type: GraphQLString, resolution: function () {return "Hello World";}}}}); export.queryType = queryType;

Запыт патлумачаны

queryType створаны ў выглядзе GraphQLObjectType і называецца Query.

У палях мы вызначаем розныя канчатковыя кропкі.

Таму тут мы дадамо канчатковую кропку пад назвай "Прывітанне".

Прывітанне мае тып GraphQLString, што азначае, што гэтая канчатковая кропка мае тып вяртання радка. Тып GraphQLString замест String, таму што гэта схема GraphQL. Так што непасрэдна са радком не атрымаецца.

Рэзалютар вызначае дзеянні, якія неабходна распачаць, калі выклікаецца канчатковая кропка. Тут трэба вярнуць радок "Hello World".

Нарэшце, мы экспартуем тып запыту export.queryType = queryType. Гэта гарантуе, што мы можам імпартаваць яго ў server.js.

Запусціце прыкладанне

Запусціце прыкладанне з дапамогай наступнай каманды:

Вузел Server.js

Дадатак працуе на localhost: 5000 / graphql.

Вы можаце праверыць прыкладанне, перайшоўшы ў localhost: 5000 / graphql.

Гэты URL працуе з вэб-інтэрфейсам карыстальніка Graphiql, як паказана на наступным экране.

Увод знаходзіцца злева, а выхад справа.

Калі ласка, увядзіце наступны запіс

{Прывітанне}

Вынікам гэтага з'яўляецца наступны вынік

{"Даты": {"Прывітанне": "Прывітанне, свет"}}

Віншую

Вы стварылі сваю першую канчатковую кропку GraphQL.

Дадайце яшчэ канчатковыя кропкі

Мы створым дзве новыя канчатковыя кропкі:

  • фільм: гэтая канчатковая кропка вяртае фільм з паказаным ідэнтыфікатарам фільма
  • Дырэктар: Гэтая канчатковая кропка вяртае дырэктара з ідэнтыфікатарам дырэктара. Усе фільмы гэтага рэжысёра таксама вяртаюцца.

Дадайце дадзеныя

Звычайна прыкладанне чытае дадзеныя з базы дадзеных. У гэтым уроку, дзеля прастаты, мы будзем жорстка зашыфроўваць дадзеныя ў сам код.

Стварыце файл з імем data.js і дадайце наступны код.

// Жорсткі код некаторых дадзеных для фільмаў і рэжысёраў Let Films = [{id: 1, Назва: "Film 1", Год: 2018, DirectorId: 1}, {id: 2, Name: "Movie 2", Year: 2017 , DirectorId: 1}, {id: 3, Name: "Фільм 3", Год: 2016, DirectorId: 3}]; хай рэжысёры = [{id: 1, Імя: "Дырэктар 1", Узрост: 20}, {id: 2, Імя: "Дырэктар 2", Узрост: 30}, {id: 3, Імя: "Дырэктар 3", Узрост: 40}]; export.movies = фільмы; export.directors = дырэктары;

Гэты файл утрымлівае дадзеныя фільма і рэжысёра. Мы будзем выкарыстоўваць дадзеныя ў гэтым файле для нашых канчатковых пунктаў.

Дадайце ў запыт канчатковую кропку фільма

Новыя канчатковыя кропкі дадаюцца да queryType у файле query.js.

Код канчатковай кропкі фільма паказаны ніжэй:

Фільм: {тып: movieType, аргументы: {id: {тып: GraphQLInt}}, рашэнне: функцыя (крыніца, аргументы) {return _.find (фільмы, {id: args.id}); }}

Тыпам вяртання гэтай канчатковай кропкі з'яўляецца movieType, які будзе вызначаны ў бліжэйшы час.

Параметр args пазначае ўваход для канчатковай кропкі фільма. Уваход для гэтай канчатковай кропкі - ідэнтыфікатар тыпу GraphQLInt.

Функцыя дазволу вяртае фільм, адпаведны ідэнтыфікатару, са спісу фільмаў. find - гэта функцыя з бібліятэкі lodash, якая выкарыстоўваецца для пошуку элемента ў спісе.

Поўны код для query.js прыведзены ніжэй:

const {GraphQLObjectType, GraphQLString, GraphQLInt} = патрабаваць ('graphql'); const _ = патрабаваць ('lodash'); const {movieType} = патрабаваць ('./ types.js'); хай {movies} = патрабуе ('./ data.js'); // Вызначце запыт const queryType = new GraphQLObjectType ({name: 'Query', поля: {Hello: {Type: GraphQLString, resolution: function () {return "Hello World";}}, фільм: {Type: movieType, Аргументы: {id: {type: GraphQLInt}}, рашэнне: функцыя (крыніца, аргументы) {return _.find (фільмы, {id: args.id});}}}}); export.queryType = queryType;

З кода вышэй мы бачым, што movieType насамрэч вызначаны ў type.js.

Дадайце ўласны тып movieType

Стварыце файл пад назвай type.js.

Дадайце наступны код у type.js

const {GraphQLObjectType, GraphQLID, GraphQLString, GraphQLInt} = патрабаваць ('graphql'); // Вызначце тып фільма movieType = new GraphQLObjectType ({name: "Film", поля: {id: {type: GraphQLID}, назва: {type: GraphQLString}, год: {type: GraphQLInt}, DirectorId: {type: GraphQLID} }}); export.movieType = movieType;

Відаць, што movieType створаны як GraphQLObjectType.

У ім ёсць 4 палі: ідэнтыфікатар, імя, год і дырэктарId. Тыпы для кожнага з гэтых палёў таксама паказваюцца пры іх даданні.

Гэтыя палі паходзяць непасрэдна з дадзеных. У гэтым выпадку гэта будзе са спісу фільмаў.

Дадайце запыт і ўвядзіце канчатковую кропку дырэктара

Як і ў фільме, можна дадаць канчатковую кропку рэжысёра.

У query.js канчатковую кропку дырэктара можна дадаць наступным чынам:

Дырэктар: {тып: DirectorType, аргументы: {id: {type: GraphQLInt}}, рашэнне: функцыя (крыніца, аргументы) {return _.find (дырэктары, {id: args.id}); }}

дырэктар Тып можа быць дададзены да type.js наступным чынам:

// Вызначце рэжысёрскі тып DirectorType = новы GraphQLObjectType ({Імя: "Дырэктар", палі: {id: {тып: GraphQLID}, імя: {тып: GraphQLString}, узрост: {тып: GraphQLInt}, фільмы: {тып: новы GraphQLList (movieType), рашэнне (крыніца, аргументы) {return _.filter (фільмы, {DirectorId: source.id});}}}});

Пачакай хвілінку Рэжысёрскі тып некалькі адрозніваецца ад фільма. Чаму гэта?

Чаму ёсць функцыя дазволу ў DirectorType? Да гэтага часу мы бачылі, што функцыі дазволу былі даступныя толькі ў запыце ...

Спецыяльнасць рэжысёрскі тып

Калі называецца канчатковая кропка рэжысёра, мы павінны вярнуць падрабязнасці рэжысёра і любыя фільмы, якія рэжысёр кіраваў.

Першыя 3 поля ідэнтыфікатар, імя, узрост у DirectorType простыя і паходзяць непасрэдна з дадзеных (спіс дырэктараў).

Чацвёртае поле - "Фільмы", павінна ўтрымліваць спіс фільмаў гэтага рэжысёра.

Па гэтай прычыне адзначым, што полем для тыпу фільма з'яўляецца GraphQLList from movieType (спіс фільмаў).

Але як менавіта мы знойдзем усе фільмы, знятыя гэтым рэжысёрам?

Для гэтага ў нас ёсць функцыя дазволу ў галіне фільмаў. Уваходы для гэтай функцыі дазволу - гэта крыніца і аргументы.

Крыніца змяшчае дадзеныя бацькоўскага аб'екта.

Скажам, палі id = 1, name = "Выпадковы" і ўзрост = 20 для рэжысёра. Тады source.id = 1, source.name = "Выпадковае" і source.age = 20

У гэтым прыкладзе функцыя дазволу знаходзіць усе фільмы, дзе рэжысёр ідэнтыфікуе адпавядае ідэнтыфікатару неабходнага рэжысёра.

Кодэкс

Увесь код гэтага прыкладання даступны ў гэтым сховішча GitHub

Тэставанне прыкладання

Зараз давайце правяраем прыкладанне для розных сцэнарыяў.

Запусціце прыкладанне з вузла server.js.

Перайдзіце да localhost: 5000 / graphql і паспрабуйце наступныя запісы.

Фільм

Уваход:

{Фільм (ID: 1) {імя}}

Выданне:

{"Даты": {"movie": {"name": "Фільм 1"}}}

З інфармацыі, прыведзенай вышэй, мы бачым, што кліент можа запытаць менавіта тое, што хоча, а GraphQL гарантуе вяртанне толькі гэтых параметраў. Тут запытваецца толькі поле імя, і толькі тое, што адпраўляецца назад сервера.

У фільме (ID: 1) ідэнтыфікатар - гэта ўваходны параметр. Мы просім сервер адправіць фільм назад з ідэнтыфікатарам 1.

Уваход:

{Фільм (ID: 3) {імя, я б год}}

Выданне:

{"Даты": {"movie": {"name": "Movie 3", "id": "3", "Year": 2016}}}}}

У прыведзеным вышэй прыкладзе, запытваюцца палі Імя, ідэнтыфікатар і год. Сервер адпраўляе назад усе гэтыя палі.

Дырэктар

Уваход:

{Дырэктар (id: 1) {імя я б, узрост}}

Выданне:

{"Даты": {"Дырэктар": {"Імя": "Дырэктар 1", "ІД": "1", "Узрост": 20}}}

Уваход:

{Рэжысёр (id: 1) {імя я б, узрост, фільмы {імя, год}}}

Выданне:

{"Даты": {"Рэжысёр": {"Імя": "Дырэктар 1", "ІД": "1", "Узрост": 20, "Фільмы": [{"назва": "Фільм 1", " Год ": 2018}, {" назва ":" Фільм 2 "," год ": 2017}]}}}}

У прыкладзе вышэй мы бачым прадукцыйнасць GraphQL. Мы заяўляем, што хочам дырэктара з ідэнтыфікатарам 1. Мы таксама заяўляем, што хочам усіх фільмаў гэтага рэжысёра. І кірунак, і поле фільма можна наладзіць, і кліент можа запытаць менавіта тое, што хоча.

Гэта можа быць распаўсюджана і на іншыя палі і тыпы. Напрыклад, мы можам запусціць запыт, як знайсці дырэктара з ідэнтыфікатарам 1. Вы шукаеце ўсе фільмы для гэтага рэжысёра. Знайдзіце акцёраў для кожнага фільма. Атрымаеце 5 лепшых фільмаў для кожнага акцёра і гэтак далей. Для гэтага запыту нам трэба ўказаць адносіны паміж тыпамі. Затым кліент можа запытаць любыя жаданыя адносіны.

Віншую

Цяпер вы ведаеце асноўныя паняцці GraphQL.

Больш падрабязную інфармацыю аб GraphQL чытайце ў дакументацыі

Пра аўтара

Я люблю тэхналогіі і сачу за поспехамі ў гэтай галіне. Мне таксама падабаецца дапамагаць іншым з маімі тэхналагічнымі ведамі.

Вы можаце звязацца са мной праз мой уліковы запіс LinkedIn https://www.linkedin.com/in/aditya1811/

Вы таксама можаце сачыць за мной у Twitter https://twitter.com/adityasridhar18

Мой сайт: https://adityasridhar.com/

Першапачаткова апублікаваны на adityasridhar.com.