Введение в GraphQL: сложные операции и переменные


GraphQL — это язык запросов для среды выполнения на стороне сервера и API для выполнения запросов с использованием системы типов для наших данных.

Рассмотрим более сложные операции GraphQL, в том числе передачу переменных, директив, мутаций и др.

Переменные

Аргументы для запросов в большинстве приложений должны быть динамическими. Передавать динамические аргументы непосредственно в строку запроса было бы не лучшим решением.

К счастью, GraphQL позволяет передавать переменные в запрос операций.

Например, можно написать:

query PersonName($id: Int) { person(id: $id) { name } }

и передать тем самым переменную $id в запрос person.

Затем можно передать переменные через объект, чтобы сделать запрос:

{ "id": 1000 }

В качестве ответа получаем подобное:

{ "data": { "person": { "name": "Jane" } } }

Определения переменных

Определения переменных начинаются с префикса $ \, затем ставится имя переменной, и потом идёт тип переменной.

В приведённом нами примере имя переменной — $id, а тип переменной — Int.

Все объявленные переменные должны быть скалярного, перечисляемого или другого типа входного объекта.

Чтобы передать в поле сложный объект, необходимо знать тип входных данных, соответствующий ему на сервере.

Переменные по умолчанию

Для переменных можно задавать стандартные значения:

query PersonName($id: Int = 1) { person(id: $id) { name } }

Здесь мы добавили = 1 после $id: Int, установив для переменной $id стандартное значение, равное 1.

Директивы

Для динамического изменения структуры и формы запросов, использующих переменные, можно задействовать директивы.

Например, чтобы сделать наш запрос динамическим, включим в него директивы:

query Person($id: Int, $withFriends: Boolean!) { person(id: $id) { name friends @include(if: $withFriends) { name } } }

В этом коде директива @include(if: $withFriends) включает friends при условии, если $withFriends будет true.

Поэтому при выполнении запроса со следующими переменными:

{ "id": 1000, "withFriends": false }

В качестве ответа мы получим подобное:

{ "data": { "person": { "name": "Jane" } } }

Директива прикрепляется к полю или включению фрагмента и может влиять на выполнение запроса желаемым для сервера способом.

Базовая спецификация GraphQL имеет две директивы, возможность использования которых должна быть в любой совместимой с ней серверной реализации GraphQL:

  • @include(if: Boolean) — включаем это поле, только если аргумент будет true;
  • @skip(if: Boolean) — пропускаем это поле, если аргумент будет true.

Такой подход помогает при работе со строками, когда приходится добавлять и удалять поля в запросе.

Мутации

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

Они отличаются от запросов тем, что начинаются с ключевого слова mutation.

Например, можно определить мутацию следующим образом:

mutation CreatePerson($firstName: String, $lastName: String) { createPerson(firstName: $firstName, lastName: $lastName) { firstName lastName } }

Тогда при выполнении такого запроса:

{ "firstName": "Joe", "lastName": "Smith" }

можно ожидать такой ответ:

{ "data": { "createPerson": { "firstName": "Joe", "lastName": "Smith" } } }

Здесь мы возвращаем те же поля firstName и lastName, что указывали в запросе.

В мутации, как и в запросе, несколько полей. Поля мутации выполняются последовательно, то есть при отправке в одном запросе двух мутаций createPerson первая завершится прежде, чем начнётся вторая.

Встраиваемые фрагменты

С помощью запросов GraphQL можно определять типы интерфейсов и объединений. С этой целью используем встраиваемые фрагменты для доступа к данным в базовом конкретном типе.

Например, напишем следующий запрос:

query Thing($id: Int!) { person(id: $id) { name ... on Person{ gender } ... on Robot{ memory } } }

Здесь оператор ...on указывает на то, что в запрос включаются встраиваемые фрагменты Person и Robot.

Эти фрагменты также могут быть встраиваемыми благодаря наличию типа.

Метаполя

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

Например, при выполнении следующего запроса:

{ search(text: "an") { __typename ... on Human { name } ... on Robot { name } } }

… от сервера может поступить такой ответ:

{ "data": { "search": [ { "__typename": "Human", "name": "Hans" }, { "__typename": "Robot", "name": "Jane" } ] } }

Заключение

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

Мы можем использовать переменные для придания динамичности запросам, задействуя переменные данные и директивы для условного включения данных в ответ.

Наконец, с помощью свойства __typename мы можем использовать встраиваемые фрагменты для типов объединений и получать тип данных, возвращаемых в ответе.


Перевод статьи John Au-Yeung: Introduction to GraphQL — Variables and Complex Operations


Поделиться статьей:


Вернуться к статьям

Комментарии

    Ничего не найдено.