Что такое GraphQL
GraphQL — это язык запросов к API, предназначенный для упрощения эффективной коммуникации между клиентами и серверами. Он позволяет пользователю точно указывать, какие данные нужны в ответе, что помогает избегать больших объектов ответа и множественных вызовов, которые иногда встречаются в REST API.
Сервисы GraphQL определяют контракт, через который клиент может взаимодействовать с сервером. Клиенту не нужно знать, где находятся данные. Вместо этого клиенты отправляют запросы серверу GraphQL, который извлекает данные из соответствующих источников. Поскольку GraphQL платформенно нейтрален, его можно реализовать на широком спектре языков программирования и использовать для взаимодействия практически с любым хранилищем данных.
Как работает GraphQL
Схемы GraphQL определяют структуру данных сервиса, перечисляя доступные объекты (называемые типами), поля и взаимосвязи.
Данными, описанными в схеме GraphQL, можно управлять с помощью трех типов операций:
Запросы извлекают данные.
Мутации добавляют, изменяют или удаляют данные.
Подписки похожи на запросы, но устанавливают постоянное соединение, через которое сервер может проактивно отправлять данные клиенту в указанном формате.
Все операции GraphQL используют одну и ту же конечную точку и, как правило, отправляются как POST-запрос. Это существенно отличается от REST API, которые используют разные конечные точки для разных операций и множество методов HTTP. В GraphQL тип и имя операции определяют, как обрабатывается запрос, а не конечная точка или используемый метод HTTP.
Сервисы GraphQL обычно отвечают на операции JSON-объектом в запрошенной структуре.
Что такое схема GraphQL?
В GraphQL схема представляет собой контракт между фронтендом и бэкендом сервиса. Она определяет доступные данные в виде набора типов, используя человекочитаемый язык описания схем. Эти типы затем реализуются сервисом.
Большинство определенных типов — это объектные типы, которые описывают доступные объекты, а также их поля и аргументы. Каждое поле имеет свой тип, который может быть либо другим объектом, либо скаляром, перечислением, объединением, интерфейсом или пользовательским типом.
Ниже приведен простой пример определения схемы для типа Product. Оператор ! указывает, что поле не может быть null при вызове (то есть обязательно).
Схемы также должны включать как минимум один доступный запрос. Обычно они также содержат сведения о доступных мутациях.
Что такое запросы GraphQL?
Запросы GraphQL извлекают данные из хранилища. Они примерно соответствуют GET-запросам в REST API.
Запросы обычно имеют следующие ключевые компоненты:
Тип операции
query. Технически необязателен, но рекомендуется, так как явно сообщает серверу, что входящий запрос — это запрос на получение данных.Имя запроса. Может быть любым. Имя запроса необязательно, но рекомендуется, поскольку помогает при отладке.
Структура данных. Это те данные, которые запрос должен вернуть.
Необязательно — один или несколько аргументов. Они используются для создания запросов, возвращающих сведения о конкретном объекте (например, «верни имя и описание товара с ID 123»).
Ниже показан пример запроса с именем myGetProductQuery, который запрашивает поля name и description у товара с id равным 123.
Обратите внимание, что тип Product может содержать в схеме больше полей, чем запрашивается здесь. Возможность запрашивать только необходимые данные — одна из ключевых особенностей гибкости GraphQL.
Что такое мутации GraphQL?
Мутации изменяют данные — добавляют, удаляют или редактируют их. Они примерно соответствуют методам POST, PUT и DELETE в REST API.
Как и запросы, мутации имеют тип операции, имя и структуру возвращаемых данных. Однако мутации всегда принимают входные данные определенного типа. Это может быть встроенное значение, но на практике обычно передается как переменная.
Ниже приведен пример мутации для создания нового товара и соответствующего ответа. В данном случае сервис настроен на автоматическое присвоение ID новым товарам, который был возвращен по запросу.
Компоненты запросов и мутаций
Синтаксис GraphQL включает несколько общих компонентов для запросов и мутаций.
Поля
Все типы GraphQL содержат элементы запрашиваемых данных, называемые полями. При отправке запроса или мутации вы указываете, какие поля API должен вернуть. Ответ отражает содержимое, указанное в запросе.
Ниже показан запрос для получения идентификатора и имени всех сотрудников и соответствующий ответ. В данном случае id, name.firstname и name.lastname — это запрошенные поля.
Аргументы
Аргументы — это значения, которые передаются для конкретных полей. Допустимые аргументы для типа определяются в схеме.
При отправке запроса или мутации, содержащих аргументы, сервер GraphQL определяет, как отвечать, исходя из своей конфигурации. Например, он может вернуть конкретный объект вместо сведений обо всех объектах.
Ниже приведен пример запроса getEmployee, принимающего идентификатор сотрудника в качестве аргумента. В этом случае сервер возвращает только данные сотрудника, соответствующего этому идентификатору.
Переменные
Переменные позволяют передавать динамические аргументы, а не указывать их непосредственно в самом теле запроса.
Запросы на основе переменных используют ту же структуру, что и запросы с встроенными аргументами, но некоторые элементы запроса берутся из отдельного словаря переменных в формате JSON. Они позволяют переиспользовать общую структуру для множества запросов, изменяя только значение самой переменной.
При построении запроса или мутации, использующих переменные, необходимо:
Объявить переменную и ее тип.
Добавить имя переменной в соответствующее место в запросе.
Передать ключ и значение переменной из словаря переменных.
Ниже приведен тот же запрос, что и в предыдущем примере, но с передачей ID в виде переменной, а не как части строки запроса.
В этом примере переменная объявлена в первой строке ($id: ID!). Символ ! указывает, что это обязательное поле для данного запроса. Затем она используется как аргумент во второй строке (id:$id). Наконец, значение переменной задается в JSON-словаре переменных. Информацию о том, как тестировать эти уязвимости, см. в разделе GraphQL.
Алиасы
Объекты GraphQL не могут содержать несколько свойств с одинаковым именем. Например, следующий запрос недействителен, поскольку пытается вернуть тип product дважды.
Алиасы позволяют обойти это ограничение, явно задавая имена свойств, которые вы хотите получить от API. Вы можете использовать алиасы, чтобы вернуть несколько экземпляров одного и того же типа объекта в одном запросе. Это помогает уменьшить количество вызовов API.
В примере ниже запрос использует алиасы для задания уникального имени для каждого из товаров. Теперь запрос проходит валидацию, и сведения возвращаются.
Фрагменты
Фрагменты — это переиспользуемые части запросов или мутаций. Они содержат подмножество полей, принадлежащих соответствующему типу.
После определения их можно включать в запросы или мутации. Если впоследствии они изменяются, изменения применяются во всех запросах или мутациях, которые вызывают фрагмент.
Ниже показан запрос getProduct, в котором сведения о товаре содержатся во фрагменте productInfo.
Подписки
Подписки — особый тип запросов. Они позволяют клиентам установить длительное соединение с сервером, чтобы сервер мог отправлять клиенту обновления в реальном времени без необходимости постоянного опроса данных. Они в первую очередь полезны для небольших изменений больших объектов и для функциональности, требующей небольших обновлений в реальном времени (например, системы чатов или совместного редактирования).
Как и обычные запросы и мутации, запрос подписки определяет форму возвращаемых данных.
Подписки обычно реализуются с использованием WebSocket.
Интроспекция
Интроспекция — встроенная функция GraphQL, позволяющая запрашивать у сервера сведения о схеме. Она часто используется приложениями, такими как IDE для GraphQL и инструменты генерации документации.
Как и в обычных запросах, вы можете указать поля и структуру желаемого ответа. Например, вы можете захотеть, чтобы ответ содержал только имена доступных мутаций.
Интроспекция может представлять серьезный риск раскрытия информации, поскольку позволяет получить потенциально чувствительные сведения (например, описания полей) и помогает злоумышленнику понять, как взаимодействовать с API. В продакшене рекомендуется отключать интроспекцию.
Last updated