Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. JavaScript

Что такое GraphQL?

by
Read Time:10 minsLanguages:

Russian (Pусский) translation by Marat Amerov (you can also view the original English article)

Обзор

GraphQL - это новый и захватывающий API для специальных запросов и манипуляций. Он чрезвычайно гибкий и обеспечивает множество преимуществ. Он особенно подходит для отображения данных, организованных в виде графов и деревьев. Facebook разработал GraphQL в 2012 году и открыл его в 2015 году.

Он быстро взлетел и стал одной из самых популярных технологий. Многие инновационные компании внедрили и используют GraphQL в продакшене. В этом уроке вы узнаете:

  • принципы GraphQL
  • в чем различия с REST
  • как проектировать схемы
  • как настроить GraphQL сервер
  • как реализовать запросы и мутации
  • и несколько дополнительных тем

Где GraphQL наиболее оптимален?

GraphQL лучше всего подходит, когда ваши данные организованы в иерархии или графе, и интерфейс должен иметь доступ к различным подмножествам этой иерархии или графа. Рассмотрим приложение, которое работает с данными NBA. У вас есть команды, игроки, тренеры, чемпионаты и много информации о каждом из них. Вот несколько примеров запросов:

  • Каковы имена игроков в текущем списке Golden State Warriors?
  • Каковы имена, рост и возраст стартеров Вашингтонских волшебников?
  • Какой активный тренер имеет большинство чемпионатов?
  • Для каких команд и в какие годы тренер выигрывал свои чемпионаты?
  • Какой игрок выиграл большинство наград MVP?

Я мог бы найти сотни таких запросов. Представьте себе, что вам нужно разработать API, чтобы вывести все эти запросы на фронтeнд и иметь возможность легко расширять API новыми типами запросов, так как ваши пользователи или менеджер по продуктам придумывают новые интересные задачи.

Это не тривиально. GraphQL был разработан для решения этой конкретной проблемы, и с одной конечной точкой API он обеспечивает огромную мощность, скоро вы это увидите.

GraphQL vs. REST

Прежде чем погрузиться в детали GraphQL, давайте сравним его с REST, который в настоящее время является самым популярным типом web-API.

REST следует модели, ориентированной на ресурсы. Если наши ресурсы - игроки, тренеры и команды, то, вероятно, будут такие конечные точки как:

  • /players
  • /players/<id>
  • /coaches
  • /coaches/<id>
  • /teams
  • /teams/<id>

Часто конечные точки без id просто возвращают список идентификаторов, а конечные точки с идентификатором возвращают полную информацию об одном ресурсе. Разумеется, вы можете разрабатывать свой API другими способами (например, конечная точка /players может возвращать также имя каждого игрока или всю информацию о каждом игроке).

Проблема с этим подходом в динамической среде заключается в том, что вы либо недополучите (например, вы получаете только идентификаторы и нуждаетесь в дополнительной информации), либо чрезмерно выбираете (например, получаете полную информацию о каждом игроке, когда вас просто интересует имя).

Это тяжело решаемые проблемы. При недополучении, если вы получаете 100 идентификаторов, вам нужно выполнить 100 отдельных вызовов API, чтобы получить информацию о каждом игроке. При чрезмерной выборке вы тратите много времени на бекенде и пропускную способность сети, готовя и передавая большое количество данных, которые не нужны.

Есть способы решить проблему с помощью REST. Вы можете проектировать множество заказных конечных точек, каждая из которых возвращает именно нужные вам данные. Это решение не является масштабируемым. Трудно поддерживать API. Трудно его развить. Трудно документировать и использовать его. Трудно поддерживать его, когда между этими заказными конечными точками существует много перекрытий.

Рассмотрим эти дополнительные конечные точки:

  • /players/names
  • /players/names_and_championships
  • /team/starters

Другой подход заключается в том, чтобы сохранить небольшое количество общих конечных точек, но предоставить множество параметров запроса. Это решение позволяет избежать многих проблем с конечными точками, но оно идет вразрез с принципами модели REST, а также сложно масштабируется и поддерживается консистентность.

Вы могли бы сказать, что GraphQL использует этот подход до предела. Он не мыслит с точки зрения четко определенных ресурсов, а вместо этого в терминах субграфов всего домена.

Система типов GraphQL

GraphQL моделирует домен, используя систему типов, состоящую из типов и атрибутов. Каждый атрибут имеет тип. Тип атрибута может быть одним из основных типов, которые GraphQL предоставляет как ID, String и Boolean, или определенный пользователем тип. Узлами графа являются пользовательские типы, а ребра - это атрибуты, которые имеют определяемые пользователем типы.

Например, если тип "Player" имеет атрибут "team" с типом "Team", то это означает, что между каждым игровым узлом есть узел с узлом команды. Все типы определены в схеме, которая описывает объектную модель домена GraphQL.

Вот очень упрощенная схема для домена NBA. У игрока есть имя, команда, с которой он больше всего связан (да, я знаю, что игроки иногда переходят из одной команды в другую) и количество чемпионатов, которые выиграл игрок.

У команды есть имя, множество игроков и количество чемпионатов, которые выиграла команда.

Существуют также предопределенные точки входа. Это запрос, мутация и подписка. Передняя часть связывается с бекендом через точки входа и настраивает их для своих нужд.

Вот запрос, который просто возвращает всех игроков:

Восклицательный знак означает, что значение не может быть null. В случае запроса allPlayers он может возвращать пустой список, но не null. Кроме того, это означает, что в списке нет null (поскольку он содержит Player!).

Настройка сервера GraphQL

Вот полноценный сервер GraphQL на основе node-express. Он имеет хардкод-решение для хранения данных в памяти. Обычно данные хранятся в базе данных или получаются из другого сервиса. В данном случае, данные определены прямо в коде (извинения заранее, если ваша любимая команда или игрок этого не вбиты):

Библиотеки, которые я использую:

Это код для построения схемы. Обратите внимание, что я добавил пару переменных в запрос root allPlayers.

Вот ключевая часть: подключение запросов и фактическое обслуживание данных. Объект rootValue может содержать несколько корней.

Здесь есть только allPlayers. Он извлекает offset и limit по аргументам, разрезает данные всех игроков, а затем устанавливает команду для каждого игрока на основе team id. Это делает каждого игрока вложенным объектом.

Наконец, вот конечная точка graphql, передающая схему и объект значения корня:

Установка graphiql в true позволяет нам тестировать сервер с помощью потрясающей встроенной графической среды GraphQL. Я настоятельно рекомендовал его для экспериментов с различными запросами.

Специальные запросы с помощью GraphQL

Все установлено. Давайте перейдем к http://localhost:3000/graphql и повеселимся.

Мы можем начать с простого списка имен игроков:

Хорошо. Здесь у нас есть суперзвезды. Без сомнений. Пойдем на что-то более интересное: начнем со offset 4 и получим 2 игрока. Для каждого игрока, вернуть свое имя и сколько чемпионатов они выиграли, а также название своей команды и сколько чемпионатов выиграла команда.

Итак, Коби Брайант выиграл пять чемпионатов с Лейкерс, которые выиграли 16 чемпионатов в целом. Кевин Дюран выиграл только один чемпионат с воинами, который выиграл пять чемпионатов.

Мутации GraphQL

Волшебный Джонсон был волшебником на корте. Но он не мог этого сделать без своего приятеля Карема Абдул-Джаббара. Давайте добавим Карема в нашу базу данных. Мы можем определить мутации GraphQL для выполнения таких операций, как добавление, обновление и удаление данных с нашего графа.

Во-первых, давайте добавим в схему тип мутации. Он немного похож на сигнатуру функции:

Затем нам нужно реализовать его и добавить к корневому значению. Реализация просто берет параметры, предоставленные запросом, и добавляет новый объект к data['allPlayers']. Он также гарантирует правильную настройку команды. Наконец, он возвращает нового игрока.

Чтобы на самом деле добавить Карема, мы можем вызвать мутацию и запросить возвращаемого игрока:

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

Дополнительные Темы

Подписки

Подписки - еще одна киллер-фича GraphQL. С подписками клиент может подписаться на события, которые будут запущены при изменении состояния на серверe. Подписки были представлены на более позднем этапе и реализованы различными фреймворками по-разному.

Валидация

GraphQL проверяет каждый запрос или мутацию на схему. Это большое преимущество, когда входные данные имеют сложную форму. Вам не нужно писать раздражающий и хрупкий код проверки. GraphQL позаботится об этом за вас.

Интроспекция схемы

Вы можете проверить и запросить текущую схему. Это дает вам мета-полномочия для динамического обнаружения схемы. Вот запрос, который возвращает все имена типов и их описание:

Заключение

GraphQL - это захватывающая новая технология для API, которая предоставляет много преимуществ по сравнению с REST API. За этим стоит сильное сообщество, не говоря уже о Facebook. Я предсказываю, что он станет главным в кратчайшие сроки.. Попробуйте. Вам понравится.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.