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



Книга Введение в 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 мы можем использовать встраиваемые фрагменты для типов объединений и получать тип данных, возвращаемых в ответе.


320   0  

Comments

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