В первом уроке мы отправили простой запрос: «дай мне пользователя и его имя». Настоящему приложению нужно больше. Пользователь вводит id в форму — как подставить его в запрос? Нужно загрузить сразу двух пользователей. Десять экранов запрашивают одни и те же поля — неужели копировать их десять раз? Для всего этого в запросах GraphQL есть инструменты: аргументы, переменные, алиасы, фрагменты и директивы. Представьте бланк заказа в кафе. Блюда в бланке — это поля, пометки вроде «без лука» — аргументы, а пустые клеточки, которые вы каждый раз заполняете по-новому, — переменные. Алиас позволяет заказать одно блюдо дважды, подписав «для Лейлы» и «для Мурада», а фрагмент — это «комбо-набор», который не нужно расписывать заново.
Анатомия запроса
Запрос GraphQL — это текст в особом формате. Вот полный запрос с именем GetUser; пока не вчитывайтесь в каждую деталь, мы разберём их по очереди:
query GetUser($id: ID!) {
user(id: $id) {
name
email
}
}Из чего он состоит:
- Тип операции —
query,mutationилиsubscription. Здесь это чтение данных. - Имя операции —
GetUser. Его придумываете вы. Сервер сработает и без имени, но с именем запрос проще найти в логах, инструментах отладки и отчётах об ошибках. - Определение переменных —
($id: ID!). Заготовка под значение, которое придёт отдельно. Подробно — ниже. - Поле с аргументом —
user(id: $id): полеuserиз типаQueryи его аргументid. - Набор полей (selection set) — всё, что внутри фигурных скобок
{ }: перечень того, что вы хотите получить.
Наборы полей вкладываются друг в друга сколько угодно раз — как рёбра графа из прошлого урока: user { posts { comments { text } } }. Правило одно: у поля, которое возвращает объект (user, posts), обязательно должен быть свой набор { … }, а у скаляра (name, email) — не должно. Запрос { user(id: "1") } без набора полей — ошибка: сервер ответит Field "user" of type "User" must have a selection of subfields. «Верни всё» в GraphQL не бывает, вы всегда перечисляете нужное.
Если у запроса нет ни имени, ни переменных, слово query можно опустить: { users { name } } — так мы писали в первом уроке.
Аргументы
Аргументы передают полю параметры, как аргументы функции. Они пишутся в круглых скобках после имени поля: user(id: "1"). В схеме из прошлого урока у user один обязательный аргумент id, а у posts — необязательный published. Запросим сразу два корневых поля:
{
user(id: "1") {
name
}
posts(published: true) {
title
}
}Значения записываются почти как в JSON: строки — в двойных кавычках, числа, true, false и null — как есть, списки — [1, 2, 3]. Но есть два отличия: ключи объектов пишутся без кавычек, а значения enum — без кавычек вообще (orderBy: OLDEST). Аргументы бывают и у вложенных полей, не только у корневых.
Корневых полей в одном запросе может быть сколько угодно, и у каждого в ответе свой ключ: data.user и data.posts. Независимые поля сервер вправе выполнять параллельно.