В статье рассматривается технология GraphQL, приводится обзор достоинств и недостатков, а также сравнение с REST технологией.
Ключевые слова: GraphQL, REST, передача данных, клиент-серверная архитектура.
На сегодняшний день существует несколько интерфейсов коммуникации клиентского приложения и сервера. Они определяются способом отправления запроса, форматом передаваемых данных и форматом получаемых данных. Наиболее популярными интерфейсами коммуникации клиент-серверного приложения являются SOAP, REST, JSON API [1]. Все эти интерфейсы имеют свои достоинства и недостатки. Однако в эру развития мобильных технологий и гаджетов появляется новое значимое требование: быстрота отображения данных для мобильного интернета, который зачастую не всегда имеет большую скорость передачи данных. Более быстрой загрузки можно добиться не только увеличением скорости передачи данных, но и уменьшением количества передаваемых данных и снижением количества запросов к серверу. Для решения данной задачи была разработана технология GraphQL, предоставляющая новый гибкий интерфейс коммуникации клиентского приложения с сервером.
Технология GraphQL, разработанная компанией Facebook в 2012 году, является альтернативой REST-архитектуре. Особенность технологии GraphQL заключается в том, что она позволяет клиенту определять структуру данных, которую он хочет получить [2].
Технология GraphQL разрабатывалась для решения следующих проблем:
- Проблема множества запросов. Допустим, с сервера необходимо получить список всех пользователей и информацию о них. В REST-архитектуре для этого потребуется выполнить один запрос для получения списка всех пользователей и, в зависимости от исполнения API сервера, еще один или множество запросов для получения информации о них.
- Проблема лишних данных. Допустим, надо отобразить только имя и фамилию пользователя, а в REST-архитектуре сервер возвращает абсолютно всю информацию о нем: фамилию, имя, отчество, дату рождения и т. д.
- Зависимость архитектуры от протокола передачи данных. Архитектура REST привязана к HTTP и использует свойства, характерные только для HTTP: методы, коды состояния. Написанное приложение с архитектурой REST будет сложно перенести на другой канал связи, например, WebSockets или SFTP [3].
- Независимость кода клиента от сервера. Для устранения проблем множества запросов и лишних данных можно создавать новые методы и логику в программе. Но для этого надо одновременно изменять и клиентский код, и серверный. При этом возникает проблема версионности приложения.
GraphQL — это стандарт декларирования структуры данных и способов получения данных, который выступает дополнительным слоем между клиентом и сервером. Одной из основных отличительных особенностей GraphQL является то, что структура и объем данных определяется клиентским приложением [3].
В отличие от стандартного REST-подхода, имеющего несколько точек входа, выполняющих простые задачи, GraphQL содержит только одну точку входа, которая работает со всеми запросами. Фактически, GraphQL находится между клиентом и одним или несколькими источниками данных; он принимает запросы клиентов, перенаправляет эти запросы нужным обработчикам и возвращает необходимые данные в соответствии с переданными инструкциями.
Рассмотрим пример запроса в листинге 1. Для получения информации об авторах из города Минска, включающей имя, фамилию и перечень всех статей каждого автора, создан запрос, который указывает, какие данные необходимо получить, используя декларативную, графоподобную структуру, напоминающую формат JSON.
Листинг 1. Пример запроса GraphQL на получение информации об авторах
query {
authors(city: «Minsk») {
firstName,
lastName,
articles {
title
}
}
}
GraphQL позволяет получать данные из нескольких источников одновременно или даже из различных микросервисов, работающих на различных серверах. Структурная схема работы GraphQL представлена на рисунке 1.
Рис. 1. Структурная схема работы GraphQL
Технология GraphQL сама не может обработать входящий запрос, поэтому необходимо указать источники данных для каждого объекта в графе. Для этого созданы специальные обработчики, базовая структура которых представлена в листинге 2.
Листинг 2. Пример обработчика запроса в GraphQL
Query: {
authors(args) {
return authorsRepository.findById(args.id);
}
}
При встрече в запросе поля authors, GraphQL находит необходимый обработчик по соответствующему имени и возвращает результат его выполнения.
Помимо получения данных, GraphQL поддерживает функции их создания и изменения. Для этого существуют обработчики, называемые мутациями. Принцип их работы похож на рассмотренный выше, только данные не считываются, а обновляются. Пример запроса на мутацию представлен в листинге 3.
Листинг 3. Пример распознавателя в GraphQL
mutation {
changeUserName(id: "1",
firstName: «Ivan»,
lastName: «Ivanov»)
{
birthDay
}
}
Данная мутация обновит пользователя с идентификатором 1: установит ему новое имя и фамилию, а также вернет дату рождения этого пользователя.
Для того, чтобы технология GraphQL понимала, какие есть объекты в графе, как они связаны и какие есть мутации, существует описательный файл, называемый схемой. В схеме описаны каждый объект графа с типами данных полей, связи с другими объектами, сигнатуры мутаций.
Архитектурное решение разделения запросов и мутаций отлично сочетается с принципом CQRS (Command-query responsibility segregation) [4], который является одним из важнейших принципов построения больших и расширяемых систем. Поскольку разделение запросов на чтение и команд на изменение данных позволяет избавиться от множества проблем с неожидаемым изменением данных.
Помимо запросов и мутаций, технология GraphQL содержит другие возможности, улучшающие быстроту и простоту написания запросов. К ним относятся:
− псевдонимы — позволяют давать различные имена для объектов графа, что позволяет получать несколько объектов одного типа в одном запросе;
− фрагменты — позволяют вынести в отдельную переменную повторяющиеся названия полей для различных объектов, что уменьшает размер запроса и повышает его читаемость;
− переменные — позволяют вынести значения каких-либо аргументов из тела запроса GraphQL и передавать их отдельно, что дает возможность не изменять тело запроса для различных аргументов, таких как, например, идентификатор сущности.
Рассмотрение технологии GraphQL позволило определить пути решения проблем, изложенных выше. Проблема множества запросов устраняется указанием всех сущностей, которые нужно загрузить. Проблема лишних данных решается указанием только нужных полей. Так как все команды и запросы передаются, используя только тело запроса, то с данной технологией можно пользоваться различными протоколами передачи данных. При добавлении новой логики на клиенте, не нужно создавать новую точку входа и логику на сервере, достаточно составить новый запрос со всеми необходимыми данными, и GraphQL динамически вернет нужные данные.
У технологии GraphQL также есть свои недостатки [5]:
- Проблема вложенных запросов. Использование большого числа вложенных запросов сопровождается передачей большого объема данных. При этом один запрос выгружает почти всю базу данных, что может привести к перегрузке сервера. Во избежание этого ограничивают вложенность запросов.
- Для определения схемы требуется дополнительный код, который должен быть синхронизирован с актуальным состоянием сущностей. Однако есть библиотеки, позволяющие генерировать схемы автоматически.
- Необходимость создания дополнительной логики по поиску обработчика. Для определения нужного обработчика GraphQL разбирает и анализирует запрос, что ведет к незначительному ухудшению производительности.
- Запросы, отправленные через GraphQL, не способны кэшироваться стандартными средствами браузера, т. к. браузер кэширует только GET запросы.
Литература:
- REST — это новый SOAP — URL: https://habr.com/ru/company/mailru/blog/345184/ (дата обращения: 23.02.2019)
- Introduction to GraphQL. — URL: https://graphql.org/learn/ (дата обращения: 23.02.2019)
- Что же такое этот GraphQL? — URL: https://habr.com/ru/post/326986/ (дата обращения: 23.02.2019)
- SQRS — URL: https://ru.wikipedia.org/wiki/CQRS (дата обращения: 23.02.2019)
- GraphQL — The Good and the Bad. — URL: https://scotch.io/tutorials/graphql-the-good-and-the-bad (дата обращения: 23.02.2019)