В последнее время в интернете появилось очень много материалов о GraphQL. Его называют убийцей REST API. Давайте разберемся, что такое GraphQL и стоит ли его использовать, и действительно ли он может заменить REST.
В двух словах, GraphQL это язык запросов, который описывает как получить данные с сервера, и используется в API для загрузки данных с сервера на клиент. GraphQL имеет 3 главных особенности:
- Позволяет клиенту указать, какие конкретно данные ему нужны.
- Облегчает агрегацию данных из нескольких источников.
- Использует систему типов для описания данных.
Проблемы REST API
GraphQL появился в большом старом Facebook, но и проекты меньшего масштаба могут столкнуться с некоторыми ограничениями REST.
Представьте, что вам нужно показывать список постов пользователей, каждый из которых имеет список комментариев. Для каждого поста и для каждого комментария нужно показать краткую информацию об авторе записи.
В классическом REST API, вы должны обратиться по адресу /posts
и получить список постов, затем, для каждого поста получить информацию об авторе по адресу /posts/:id/users
, затем по адресу по адресу /posts/:id/comments
получить список комментариев, и т.д. Таким образом, чтобы отобразить такую несложную страницу, потребуется сделать достаточно много http-запросов к серверу.
Другой проблемой может быть наличие нескольких потребителей API. Если десктопная версия сайта отображает полную информацию о комментариях, включая логотип и краткую информацию об авторе, а в мобильной версии вы показываете только текст и имя автора, то для мобильной версии нам придется постоянно загружать лишние данные, которые не будут использованы для отображения.
Эти проблемы могут быть решены в рамках REST API, например введением дополнительных GET параметров, таких как ?relations=author,comments
и ?fields=id,name,image
, в которых для каждой сущности может будет указать соответственно список связанных сущностей, и список необходимых полей. Но если API достаточно большое, а в приложении требуется отображать множество связанных сущности, то реализация и поддержка таких параметров будет очень трудозатратной.
Решение
Facebook придумал очень простое решение этой проблемы: вместо того, чтобы иметь множество url для каждой сущности, создается один «умный» url, который может принимать сложные запросы и затем выдавать данные клиенту в том виде, в котором они ему требуются.
Практически говоря, слой GraphQL живет между клиентом и одним или несколькими источниками данных, принимает клиентские запросы и извлекает необходимые данные в соответствии с требованиями клиента.
GraphQL API состоит из 3 основных строительных блоков: схема (schema), запросы (queries), резолверы (resolvers).
Запросы
Запрос к GraphQL серверу начинается с ключевого слова query. Отличная новость о запросах к GraphQL заключается в том, что они поддерживают вложенные поля. Также каждое поле само по себе может быть какой-либо сущностью, или массивом. Нижет представлен пример запроса для получения списка постов:
query { posts { # массив id title text author { # вложенная сущность id name } } }
Запросы также поддерживают аргументы. Если вы хотите отобразить конкретный пост, вы можете добавить аргумент id
к полю post
:
query { post(id: "1"){ id title text author{ id name } } }
Если выхотите сделать аргумент id
динамическим, вы можете объявить переменную и использовать ее в запросе (так же каждый запрос может иметь свое имя):
query getPostById($id: String) { post(id: $id){ id title text author{ id name } } }
Резолверы (resolvers)
Резолвер описывает, как и где получить данные для конкретного поля объекта. При этом резолверы не обязательно должны возвращать колонки из базы данных. Здесь важно понимать, что в GraphQL схема API и схема базы данных не связаны. Таким образом, объект Post
может иметь поле commentsCount
, резолвер для которого будет извлекать и базы данных количество всех комментариев для поста и возвращать число.
Резолвер может так же описывать, как изменить значение конкретного поля объекта. Такие резолверы называются мутациями (mutations).
Схемы
Схемы представляют из себя описание всех объектов, которые можно получить с помощью вашего API.
Основными компонентами схем в GraphQL являются типы объектов и поля, которые можно получить для этих объектов. В нашем примере типами будут Post
и Comment
, а полями id
, title
, text
, и т.д. Так как GraphQL API может быть написан на любом языке, то формат схем будет разным в каждой конкретной реализации. Разработчики языка вводят специальный псевдо-язык GraphQL schema language для описания схем без использования конкретного языка программирования.
Заключение
GraphQL может показаться сложным на первый взгляд, но если понять основные концепции, вы увидите, что многое из этого имеет смысл.
Конечно, некоторые из концепций GraphQL могут быть реализованы и в рамках REST добавлением дополнительных параметров к запросам, но если ваш API имеет много различных объектов, которые могут использоваться в различных комбинациях, то разработка и поддержка такого REST API будет не простым, и потребует написания подробной документации для всех ваших нестандартных решений. GraphQL API же по сути является самодокументируемым, т.к. схема по сути является подробным описанием всех данных, которые может предоставить ваш API.
Не важно, будете вы использовать GraphQL в своем проекте или нет, я думаю каждому будет полезно потратить время и ознакомиться с ним. Все больше и больше проектов и фреймворков начинают использовать этот язык, и возможно в ближайшие несколько лет GraphQL может стандартом де-факто при создании API, каким на сегодняшний день является REST.
Полезные ссылки
- GraphQL.org — официальный сайт с документацией, примерами использования и лучшими практиками использования GraphQL.
- graphql-php — библиотека для создания GraphQL API на PHP.
- GraphiQL — очень удобная браузерная IDE для выполнения запросов к GraphQL API.