# GraphQL (/ru/docs/requests/graphql)

Запрос GraphQL содержит запрос, его переменные и схему, по которой он написан. Echolot использует схему, чтобы
дополнять поля по мере ввода, отмечать ошибки до отправки и показывать типы рядом с ответом.

<Shot id="requests-graphql-query" alt="Catalog › Search products: вкладка «Запрос» с запросом SearchProducts, меню схемы с именем shop.graphql и числом типов и ответ JSON с totalCount и nodes" />

## Создание запроса GraphQL [#create-a-graphql-request]

Выберите **Файл › Новый запрос GraphQL** или **Новый запрос GraphQL** в меню **+** рядом с **Запросы** в боковой панели.
Введите конечную точку в поле адреса: для демо-магазина это `{{baseURL}}/graphql`. В рабочем пространстве Alpenglow
такой запрос уже есть: **Catalog › Search products**.

В редакторе есть вкладки: **Документация**, **Запрос**, **Переменные**, **Заголовки**, **Параметры**, **Авторизация**,
**Переменные** (собственные переменные запроса), **Тесты**, **Скрипты** и **Настройки**. Заголовки, авторизация, тесты и
скрипты работают так же, как у [запросов HTTP](/docs/requests).

## Запрос и переменные [#query-and-variables]

Напишите запрос на вкладке **Запрос**:

```graphql
query SearchProducts($text: String!, $first: Int = 10) {
  search(text: $text, first: $first) {
    totalCount
    nodes { sku name price { amount currency } rating stock { warehouse available } }
  }
}
```

а его переменные — в виде JSON на вкладке **Переменные**. Внутри JSON работают `{{variables}}`:

```json
{
  "text": "{{searchTerm}}"
}
```

Если в документе несколько операций, введите ту, которую нужно отправить, в поле **Операция** над запросом. Для
документа с одной операцией оставьте его пустым.

Отправьте запрос кнопкой **Отправить** или клавишами <kbd>⌘</kbd><kbd>R</kbd>.

## Как отправляется запрос [#how-the-request-is-sent]

Значок **GQL** перед адресом — это меню. В разделе **Отправлять как**:

| Вариант | Что отправляется |
| --- | --- |
| **POST (тело JSON)** | POST с `query`, `variables` и `operationName` в виде JSON. Обычный способ |
| **GET (в URL)** | `query`, `variables` и `operationName` как параметры запроса — для серверов, которые кешируют запросы GET |
| **WebSocket (graphql-transport-ws)** | WebSocket с протоколом `graphql-transport-ws` — для подписок |

Ниже ещё два переключателя:

- **Постоянные запросы (APQ)** сначала отправляет SHA-256-хеш запроса, без самого запроса. Если сервер отвечает, что не
  знает этот хеш, Echolot отправляет запрос повторно уже с текстом, чтобы сервер мог его сохранить.
- **Объединять все операции в пакет** отправляет все именованные операции документа вместе, одним массивом JSON.

## Схема [#the-schema]

Меню схемы находится справа на вкладке **Запрос**. Оно показывает файл схемы и число типов, например
`shop.graphql · … types`, или **Нет схемы**.

- **Загрузить с сервера** выполняет запрос интроспекции по адресу запроса и сохраняет результат как файл в папке
  `specs/` рабочего пространства. Выберите его снова, чтобы обновить схему.
- **Использовать схему** показывает файлы схем, которые уже есть в рабочем пространстве (`.graphql`, `.graphqls` и
  `.json`), чтобы выбрать один из них.
- **Добавить файл схемы…** принимает с вашего Mac файл SDL (`.graphql`) или результат интроспекции (`.json`).
- **Показать обозреватель схемы** открывает схему рядом с ответом.
- **Не использовать эту схему** убирает схему из запроса.

Файл схемы в `specs/` могут использовать все запросы GraphQL к этому серверу, и его можно коммитить вместе с рабочим
пространством. Когда загрузка заменяет файл схемы и схема изменилась, **Схема изменилась** перечисляет изменения как
**Ломающие**, **Опасные** и **Безопасные**, например удалённое поле или новый обязательный аргумент. Ломающие изменения —
те, из-за которых запросы, использующие удалённое или изменённое, перестают работать. В командной строке
`echolot graphql diff` сравнивает две схемы так же: см. [echolot graphql](/docs/cli/graphql).

Если схему не удаётся прочитать, меню показывает **Проблема схемы**, а панель под запросом объясняет почему.

## Дополнение, проблемы и подсказки [#completion-problems-and-hover]

Со схемой редактор запроса помогает по мере ввода:

- **Дополнение** предлагает поля, аргументы, поля ввода, типы, значения enum, переменные, директивы и фрагменты,
  подходящие к месту курсора, вместе с их документацией. Устаревшие помечены.
- **Проблемы** подчёркиваются по мере ввода: неизвестные поля, неверные типы аргументов, пропущенные обязательные
  аргументы и другое. Панель под запросом показывает первую из них и считает ошибки и предупреждения; наведите на
  неё указатель, чтобы прочитать все.
- **Подсказка** при наведении на поле или тип показывает его сигнатуру и документацию, а также устарел ли он.
- Щелчок с <kbd>⌘</kbd> по полю или типу открывает его тип в обозревателе схемы.

## Обозреватель схемы и конструктор [#the-schema-explorer-and-the-builder]

Вкладка **Схема** области ответа показывает схему запроса, даже до первой отправки. Если у запроса ещё нет схемы,
выберите там **Загрузить с сервера**.

**Обзор** начинается с **Точек входа** (**Query**, **Mutation** и **Subscription**). Нажмите тип, чтобы увидеть его
поля, поля ввода, значения enum или типы, которые его реализуют или входят в него; устаревшее помечено. «Назад»
возвращает к предыдущему типу. **Искать типы и поля** находит в схеме всё по имени.

**Конструктор** пишет запрос за вас. Выберите **query**, **mutation** или **subscription** в поле **Операция**, затем
отмечайте поля в дереве: каждая отметка добавляет поле в текст запроса, а снятие отметки убирает его. Всё, что вы
напечатали вокруг, сохраняется. Конструктор работает с операцией, названной в поле **Операция**, или с первой операцией
этого вида в документе; если её нет, он добавляет новую.

<Shot id="requests-graphql-builder" alt="Вкладка «Схема» в режиме «Конструктор» для Search products: отмечено search, раскрыт nodes, отмечены sku, name и price, а рядом запрос с теми же полями" />

## Ответы [#responses]

Ответ появляется на вкладке **Тело** в виде JSON, как любой [ответ](/docs/requests/responses). Echolot также читает то,
что GraphQL сообщает рядом с данными:

- **N ошибок GraphQL** в сводке ответа: сервер прислал массив `errors`, даже при HTTP 200. Нажмите, чтобы прочитать
  каждое сообщение и путь, к которому оно относится.
- **Частичные данные**: данные пришли вместе с ошибками, поэтому некоторые поля равны `null` из-за сбоя.
- **Расширения**: `extensions` ответа, например трассировка или сведения о стоимости.

Добавьте проверку **Ошибки GraphQL**, равную `0`, на вкладке **Тесты**, чтобы прогон падал из-за них. См.
[скрипты и тесты](/docs/requests/scripts-and-tests).

## Подписки и поэтапная доставка [#subscriptions-and-incremental-delivery]

Подписка продолжает присылать результаты, пока не завершится:

- По HTTP (**POST** или **GET**) Echolot запрашивает server-sent events, если операция — подписка.
- По **WebSocket (graphql-transport-ws)** Echolot открывает WebSocket, отправляет подписку с заголовками и
  авторизацией запроса и отвечает на пинги сервера.

Запрос с `@defer` или `@stream` приходит частями (`multipart/mixed`).

В обоих случаях в области ответа появляется вкладка **События**: каждое событие или часть по порядку, с номером, видом
(например, `next` или `part`), идентификатором и ошибками. Для `@defer` и `@stream` **Объединённый результат** вверху
показывает первый результат с применёнными ко всем последующим частям. Вкладка следит за новыми событиями, пока идёт
поток, и показывает **Прослушивание… «Остановить» завершает его.** Выберите **Отменить** (<kbd>⌘</kbd><kbd>.</kbd>),
чтобы завершить поток. Начавшийся поток не обрывается общим тайм-аутом запроса.

## Загрузка файлов [#file-uploads]

Для мутации с переменной `Upload` добавьте файл в разделе **Файлы для переменных** на вкладке **Переменные**:

1. Выберите **+**.
2. Введите переменную, например `file`, или `files.0` для первого элемента списка.
3. Введите путь к файлу относительно рабочего пространства.

Тогда POST следует спецификации multipart-запросов GraphQL: переменная в `operations` равна `null`, а файл идёт в
отдельной части.
