Найти тему
Nuances of programming

Введение в GraphQL: основные принципы использования

Оглавление

Источник: Nuances of Programming

GraphQL — это язык запросов к API-интерфейсам. Он отображает предоставляемые сервером данные, чтобы клиент смог выбрать именно то, что ему нужно.

Помимо этого, с помощью GraphQL можно получить несколько ресурсов сервера одним вызовом, а не выполнять множество вызовов REST API.

Однако трудно оценить преимущества GraphQL, не попробовав его в действии. Поэтому рассмотрим использование GraphQL на практических примерах.

Мы будем использовать GraphQL вместе с NodeJS.

Предварительные требования

Перед началом работы установите NodeJS.

Как использовать GraphQL с NodeJs

GraphQL используется с различными ЯП. Рассмотрим пример использования GraphQL с JavaScript, используя NodeJS.

Создайте папку под названием graphql-with-nodejs. Запустите команду npm init в папке проекта, чтобы создать проект NodeJS. Команда представлена ниже:

cd graphql-with-nodejs npm init

Установка зависимостей

Установите Express с помощью следующей команды:

npm install express

Установите GraphQL с помощью следующей команды. Устанавливаем GraphQL и GraphQL для Express.

npm install express-graphql graphql

Код NodeJS

Создайте файл server.js внутри проекта и скопируйте в него следующий код:

-2

Приведенный код содержит одну конечную точку (endpoint) HTTP GET с названием /hello.

Endpoint создается с помощью Express.

Теперь изменим этот код, чтобы запустить GraphQL.

Запуск GraphQL в коде

У GraphQL будет один URL endpoint с именем /graphql, который обрабатывает все запросы.

Скопируйте следующий код в server.js:

-3

Теперь пройдемся по коду.

С помощью graphqlHTTP сервер GraphQL устанавливается в URL-адрес /graphql. Он обрабатывает поступающие запросы.

Процесс установки представлен в следующих строчках кода:

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

Теперь изучим параметры внутри graphqlHTTP.

graphiql

graphiql — это веб-интерфейс, с помощью которого тестируются endpoints GraphQL. Устанавливаем значение true, чтобы было легче тестировать различные endpoints GraphQL.

schema

У GraphQL есть лишь один endpoint /graphql. Он может обладать несколькими endpoints, выполняющими различные действия. Они указаны в схеме.

Схема выполняет следующие действия:

  • Указывает различные endpoints
  • Определяет поля ввода и вывода для endpoint
  • Определяет действие, которое должно быть выполнено при достижении endpoint и так далее.

Схема определяется в коде следующим образом:

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

Схема может содержать как запрос, так и типы мутации. Мы будем рассматривать только тип query.

query

По схеме видно, что query установлен в queryType

Импортируем queryType из файла query.js с помощью следующей команды:

const {queryType} = require('./query.js');

query.js — это пользовательский файл.

query — это место, куда мы определяем endpoints типа read-only в схеме.

Создайте файл с названием query.js в проекте и скопируйте в него следующий код.

-4

query Explained

queryType создан как GraphQLObjectType с названием Query.

fields — это место, куда мы определяем endpoints.

Здесь мы добавляем один endpoint под названием hello.

hello относится к типу GraphQLString, т.е возвращает тип String. В схеме GraphQL используется тип GraphQLString вместо String. Прямое использованиеString не работает.

Функция resolve указывает действие, которое должно быть выполнено при достижении endpoint. В данном случае возвращается строка “Hello World”.

Теперь экспортируем querytype с помощью exports.queryType = queryType, чтобы убедиться, что он может быть импортирован в server.js.

Запуск приложения

Запустите приложение, используя следующую команду:

node server.js

Приложение работает на localhost:5000/graphql.

Можно протестировать приложение, перейдя на localhost:5000/graphql.

Этот URL-адрес управляет веб-интерфейсом Graphiql, как указано на скриншоте ниже.

-5

Входные данные указаны слева, а выходные — справа.

Вводим следующее:

-6

Поздравляем😃

Вы создали свой первый endpoint GraphQL.

Добавление нескольких endpoints

Создадим еще две конечных точки (endpoints):

  • movie: этот endpoint возвращает фильм, получивший ID фильма
  • director: этот endpoint возвращает режиссера, получившего ID режиссера. Он также вернет все фильмы, снятые этим режиссером.

Добавление данных

Обычно приложение прочитывает данные из Базы данных. Но в этом примере, мы будем хардкодить данные в самом коде.

Создайте файл data.js и скопируйте в него следующий код.

В этом файле содержатся данные о фильмах и режиссерах. Используем данные из этих файлов для наших endpoints.

Добавление endpoint movie в запрос

Новые endpoints будут добавлены к queryType в файл query.js.

Код для endpoint movie представлен ниже:

-7
-8

Тип возвращаемого значения этого endpoint — movieType, который скоро будет определен.

С помощью параметра args указываются входные данные для endpoint movie. Входные данные для этого endpoint — id типа GraphQLInt.

Функция resolve возвращает фильм, соответствующий id, из списка фильмов. Функция find из библиотеки lodash используется для поиска элемента в списке.

Полный код для query.js представлен ниже:

-9

Из приведенного кода видно, что movieType действительно определен в types.js.

Добавление пользовательского типа movieType

Создайте файл с названием types.js.

Добавьте следующий код в types.js:

-10

movieType создан в качестве GraphQLObjectType.

Он обладает четырьмя полями: id, name, year и directorId. Типы для каждого поля устанавливаются в процессе их добавления.

Эти поля поступают непосредственно из данных. В данном случае, из списка movies.

Добавление запроса и типа для endpoint director

В query.js endpoint director добавляется следующим образом:

-11

directorType добавляется следующим образом в types.js:

-12

Минуточку. directorType немного отличается от movieType. В чем причина?

Почему функция resolve находится внутри directorType? Ранее функции resolve присутствовали только в query…

Особенности directorType

При вызове endpoint director необходимо возвратить подробную информацию о режиссере, а также всего его фильмы.

Первые три поля id, name, age в directorType исходят непосредственно из данных (список directors).

Четвертое поле movies должно содержать список фильмов этого режиссера.

По этой причине, следует упомянуть, что тип поля movies относится к GraphQLList от movieType (Список фильмов).

Однако каким образом найти все фильмы, снятие этим режиссером?

Для этого в поле movies есть функция resolve. Входные данные для функции resolve —  source и args.

source будет содержать подробную информацию о родительском объекте.

Допустим, поля для режиссера id =1, name = “Random” и age = 20. Затем source.id =1, source.name = “Random” и source.age = 20

Таким образом, в этом примере функция resolve найдет все фильмы, в которых directorId соответствует Id запрашиваемого режиссера.

Тестирование приложения

Протестируем приложение для различных сценариев.

Запустите приложение с помощью node server.js.

Зайдите на localhost:5000/graphql и введите следующие данные.

movie

Входные данные:

-13

Приведенный пример показывает, что клиент может запросить именно то, что ему нужно, а GraphQL предоставит необходимые параметры. Сервер выдает только запрошенное поле name.

В movie(id: 1) id находится во входном параметре. Мы запросили у сервера фильм с id=1.

Входные данные:

-14

В приведенном выше примерe сервер выдает запрашиваемые поля name, id и year.

director

-15

Входные данные:

-16

Приведенный пример показывает возможности GraphQL. Нам нужен режиссер с id=1 и все его фильмы. Поля director и movie являются произвольными, поэтому клиент может запросить именно то, что ему нужно.

Аналогичным образом можно запрашивать другие поля и типы. К примеру, можно сделать запрос: Поиск режиссера с id=1 и всех его фильмов. Поиск актеров для каждого фильма, а для каждого актера 5 его лучших фильмов и так далее. Для этого запроса необходимо указать отношения между типами и тогда можно будет запросить любое необходимое отношение.

Поздравляем 😃

Теперь вы знакомы с базовыми концепциями GraphQL.

Чтобы узнать больше, можете посмотреть официальную документацию.

Читайте нас в телеграмме и vk

Перевод статьи Aditya Sridhar: An introduction to GraphQL: how it works and how to use it