В настоящее время наблюдается тенденция к росту количества информационных систем, манипулирующих большим объемом разнородных данных, зачастую, получаемых из разных источников. При работе над проектами такого рода зачастую можно столкнуться с ограничениями REST-архитектуры, которые создают некоторые сложности для разработчиков. Например, если с одним API работают несколько различных клиентов (к примеру, веб-браузер и мобильное приложение), то некоторые данные могут быть необходимы для браузерного приложения, а для мобильного клиента избыточны и сильно уменьшают эффективность его работы.
Для более эффективного, гибкого и удобного взаимодействия между клиентом и сервером был разработан GraphQL. GraphQL представляет из себя язык запросов и манипулирования данными для API. Данный язык был разработан в Facebook в 2012 году, а в 2015 году получил статус open-source проекта. За счет того, что в настоящее время GraphQL поддерживается большим сообществом компаний, создано большое количество библиотек, фреймворков и инструментов для большинства языков программирования, что сильно упрощает разработку проектов с использование GraphQL.
Основным отличием GraphQL от REST является наличие единого «умного» endpoint, который обрабатывает сложные запросы, получает, зачастую из многих источников, все необходимые данные и возвращает их в том виде, который запросил клиент.
Основой GraphQL являются схемы (schema), документы (documents) и распознаватели (resolvers).
Схема представляет из себя описание типов, которые клиент может запросить и от сервера. Так как сервисы GraphQL могут быть написаны на различных языках программирования, появилась потребность в едином синтаксисе для описания схем. Именно для этого был разработан «GraphQL schema language».
Документ представляет из себя запрос, отправляемый клиентом к серверу.
Распознаватели являются функциями на сервере, которые привязаны к определенному типу данных и «знают» как их получить.
Соответственно взаимодействие клиента и сервера происходит следующим образом:
- Клиент отправляет запрос на получение/изменение данных, который составлен в соответствии со схемой, на сервер
- Для каждого поля запроса вызывает свой распознаватель, которые получает необходимые данные
- Сервер отправляет клиенту запрошенные данные, в форме, аналогичной запросу, чаще всего в формате JSON.
Стоит более подробно рассмотреть структуру схем. В их основе лежит описание типов объектов. Для каждого объекта определяется набор полей, который может быть как скалярным типом (Int, Float, String и др.), так и объектом. Помимо обычных типов, в схеме могут содержаться интерфейсы (interface), объединения (union), перечисление (enum) и т.д. В листинге 1 представлен пример схемы, состоящий из 2-х типов.
Листинг. 1. Пример схемы GraphQL
type Author {
name: String!
books: [Book!]!
}
type Book {
name: String!
rate: Float
}
Отдельно стоит рассмотреть так называемые типы операций. Они определяют, какие запросы может выполнить клиент, то есть являются «точками входа» для API. Всего в GraphQL имеется три типа операций:
- Запрос (query) – возвращает запрошенные клиентом данные;
- Изменение (mutation) – производит манипуляции с данными и возвращает клиенту измененные данные;
- Подписка (subscription) – при обновлении данных сервер выполняет определенный в подписке запрос и передает данные клиенту.
При сравнении query и mutation необходимо рассмотреть несколько важных моментов. Во-первых, хотя технически возможно, чтобы изменение данных было реализовано через query, по соглашению предполагается, что для этого должны быть использованы мутации. Во-вторых, поля query выполняются параллельно, а поля mutation – последовательно. Ниже приведена часть схемы, описывающая тип Query (листинг 2).
Листинг. 2. Пример описания операции Query в GraphQL схеме
type Query{
book(name: String): Book
}
В документах GraphQL указывается название операции, которая должна быть выполнена. Далее идет выборка полей, которые клиент хочет получить. В случае если поле является объектом, для него также указываются поля, которые необходимо получить. В листинге 3 представлен пример GraphQL документа, а в листинге 4 представлен пример ответа, возвращаемый сервером при обработке данного документа. Как можно заметить, ответ имеет точно такую же форму, как и запрос.
Листинг. 3. Пример документа GraphQL
query {
friends {
name
others {
name
}
}
}
Листинг. 4. Пример ответа сервера
{
"data": {
"friends": {
"name": "Alex",
"others": [
{
"name": "Mike"
},
{
"name": "Jason"
},
]
}
}
}
Основными характеристиками GraphQL является следующее:
- Позволяет клиенту точно указать, какие данные ему нужны;
- Облегчает агрегацию данных из нескольких источников;
- Использует систему типов для описания данных;
- В отличие от REST, необходим только один endpoint для работы;
- GraphQL — сильно типизированный язык, что позволяет заранее оценить правильность запроса до этапа выполнения программы;
- GraphQL предоставляет возможность комбинировать запросы;
- Запросы к GraphQL API всегда возвращают ожидаемый результат, который соответствует схеме данных этого GraphQL API.
Исходя из вышесказанного можно определить случаи приложений, в которых рекомендуется использовании GraphQL:
- При использовании архитектуры с большим количеством микросервисов;
- При использовании сущностей с большим количеством полей, которые не всегда нужны;
- В случае, когда в API нужны операции, плохо укладывающиеся в парадигму CRUD;
- При использовании сущностей с большим количеством связей и вложенностей.
Но в некоторых случаях использование GraphQL не обосновано и создает некоторые сложности. Например:
- При необходимости работы с файлами;
- При необходимости поддержки многопользовательского редактирования чего-либо в реальном времени;
- При взаимодействии, требовательном к скорости, памяти или трафику;
- При необходимости стриминга данных.
Список литературы
- Что же такое этот GraphQL?. — Текст : электронный // Хабр : [сайт]. — URL: https://habr.com/ru/post/326986/ (дата обращения: 23.05.2022).
- GraphQL. — Текст : электронный // graphql.org : [сайт]. — URL: https://spec.graphql.org/June2018/ (дата обращения: 23.05.2022).
- Тонкушин, М. В. Сравнительный анализ технологий GraphQL и REST / М. В. Тонкушин, К. В. Гудков // Современные информационные технологии. – 2019. – № 29. – С. 127-131.