Site icon 8HOST.COM

Введение в GraphQL: понятия и архитектура

Мобильные и веб-приложения становятся всё более сложными, поэтому инженеры-программисты ищут новые разумные способы, чтобы улучшить взаимодействие между клиентом и сервером внутри приложения.

За последние годы значительный сдвиг в этой парадигме произвёл GraphQL, язык запросов с открытым исходным кодом и среда выполнения для управления API.

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

Из этой статьи вы узнаете про GraphQL, познакомитесь с базовой терминологией GraphQL, а также узнаете, как спецификация GraphQL соотносится с архитектурным стилем REST.

Что такое GraphQL?

GraphQL расшифровывается как Graph Query Language, язык запросов к графам. Но в отличие от других языков запросов, таких как SQL (Structured Query Language, язык структурированных запросов), это язык не для прямого взаимодействия с базой данных, а, скорее, для определения контракта, через который клиент коммуницирует с API-сервером. Спецификация GraphQL — это открытый стандарт, описывающий правила и характеристики языка. Он также содержит инструкции по выполнению запросов GraphQL.

Так как GraphQL определяется открытым стандартом, официальной сборки GraphQL не существует. Сборка GraphQL может быть написана на любом языке программирования, интегрирована с любым типом баз данных и поддерживать любой клиент (например, мобильное или веб-приложение), если она соответствует правилам, изложенным в спецификации. Одной из самых популярных коммерческих сборок GraphQL является Apollo GraphQL, который продвигает ряд клиентских и серверных сборок GraphQL. Но вам не обязательно нужен Apollo, чтобы использовать или понимать GraphQL.

Характеристики GraphQL

В дизайне GraphQL есть несколько ключевых характеристик. Запросы GraphQL декларативны и иерархичны, а схема GraphQL строго типизирована и интроспективна.

Декларативность

Запросы GraphQL декларативны, а это значит, что клиент точно укажет интересующие поля, а ответ будет содержать только заданные свойства.

В данном примере запроса GraphQL к API гипотетической фэнтезийной игры запрашивается волшебник с идентификатором «1» и поля имени и расы этого объекта.

{
  wizard(id: "1") {
    name
    race
  }
}

В ответе, который возвращается в формате JSON, будет объект data, содержащий найденный объект волшебника, с двумя полями, указанными в запросе.

{
  "data": {
    "wizard": {
      "name": "Merlin",
      "race": "HUMAN"
    }
  }
}

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

Иерархичность

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

{
  wizard(id: "1") {
    name
    spells {
      name
      attack
    }
  }
}

Теперь ответ будет содержать массив всех объектов заклинаний, связанных с конкретным волшебником. Хотя волшебники и заклинания могут храниться в разных таблицах базы данных, данные о них можно получить по одному запросу GraphQL (однако GraphQL не знает точно, в каком виде сохранены сами данные, так что это предположение).

{
  "data": {
    "wizard": {
      "name": "Merlin",
      "spells": [
        {
          "name": "Lightning Bolt",
          "attack": 2
        },
        {
          "name": "Ice Storm",
          "attack": 2
        },
        {
          "name": "Fireball",
          "attack": 3
        }
      ]
    }
  }
}

Строгая типизация

GraphQL строго типизирован, это описано в системе типов GraphQL. Типы описывают возможности значений на сервере GraphQL. Большинство программистов найдут для себя знакомыми типы GraphQL со скалярами (примитивными значениями), такими как строки, логические значения и целые числа, а также с более сложными значениями, такими как объекты.

В этом примере создается тип объекта Spell с полями, соответствующими скалярным типам String и Int.

type Spell {
  name: String!
  attack: Int
  range: Int
}

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

Самодокументирование

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

Например, вы можете узнать больше о типе Spell, используя функцию интроспекции при помощи __schema.

{
  __schema {
    types {
      name
      kind
      description
    }
  }
}

Ответ придет в формате JSON, как и прочие ответы в GraphQL:

 {
  "data": {
    "__schema": {
      "types": [
        {
          "name": "Spell",
          "kind": "OBJECT",
          "description": "A powerful spell that a wizard can read from a scroll."
        }
      ]
    }
  }
}

Клиенториентированность

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

Архитектура GraphQL

GraphQL существует на прикладном уровне между клиентом и данными. Сервер GraphQL описывает возможности, доступные в API, а клиент описывает требования запроса.

Сервер

API GraphQL определяется с единственной конечной точкой, обычно конечной точкой /graphql, у которой есть доступ ко всем возможностям сервера GraphQL. Поскольку GraphQL — технология прикладного уровня, его можно обслуживать по любому протоколу, но чаще всего это — HTTP.

Сборка сервера GraphQL может быть написана на любом языке программирования, например, при помощи промежуточного ПО express-graphql, которое позволяет создавать GraphQL API на HTTP-сервере Node/Express. GraphQL также не зависит от баз данных, и данные для приложения могут храниться в MySQL, PostgreSQL, MongoDB или любой другой базе данных. Данные могут даже быть предоставлены путем агрегирования нескольких традиционных конечных точек REST API. Все, что имеет значение, это то, что данные определены в схеме GraphQL, которая определяет API, описывая данные, доступные для запроса.

Клиент

Запросы, отправленные на сервер GraphQL, называются документами и состоят из таких операций, как запросы (для запросов на чтение) и мутации (для запросов на запись).

Несмотря на то, что существуют продвинутые клиенты GraphQL, такие как Apollo Client или Relay от Facebook, которые предоставляют механизмы для кэширования, а также дополнительные инструменты, никаких специальных клиентов для выполнения запроса к серверу GraphQL не требуется.  Простого запроса XMLHttpRequest или fetch из веб-браузера достаточно для выполнения запросов путем отправки документа GraphQL на сервер GraphQL.

Ниже приведен пример fetch-запроса к конечной точке /graphql, который передает документ GraphQL как строку в теле запроса POST.

async function fetchWizards() {
  const response = await fetch('/graphql', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      query: `{
    wizards {
      id
      name
    },
  }`,
    }),
  })
  const wizards = await response.json()

  return wizards
}

fetchWizards()

На этот запрос вернётся ответ в формате JSON.

{
  "data": {
    "wizards": [
      { "id": "1", "name": "Merlin" },
      { "id": "2", "name": "Gandalf" }
    ]
  }
}

GraphQL и REST

GraphQL и REST не являются взаимозаменяемыми концепциями, но они решают аналогичные проблемы для приложений. REST, Representational State Transfer, представляет собой архитектурный стиль программного обеспечения для обмена данными между различными системами. RESTful API – это API, который придерживается принципов и ограничений REST, включающий отсутствие состояний, возможность кеширования, принудительное разделение задач между клиентом и сервером и наличие унифицированного интерфейса, например, через URI. GraphQL, как отмечалось ранее, является спецификацией языка запросов и среды для выполнения запросов.

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

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

  GraphQL REST
Описание Язык запросов для API и серверная среда выполнения. Архитектурный стиль для разработки веб-сервисов
Сбор данных Единая конечная точка HTTP, которая отвечает на детерминированные запросы Набор конечных точек HTTP, которые обычно возвращают предварительно определенный набор данных.
Управление версиями Не рекомендовано Общее управление версиями
Коды статуса HTTP Все виды, включая ошибки, обычно это коды 200 Использует коды HTTP.
Проверка Встроенная проверка метаданных Проверку нужно выполнять ручную
Документация Встроенная система типов и интроспекция. Не самодокументируется, доступны такие инструменты, как OpenAPI
Кэшировние Нет Да
Методы запросов Запросы, изменения и подписки (по протоколу POST для HTTP) Все используемые HTTP-методы (GET, POST, PATCH, PUT, DELETE и т.д.)
Тип содержимого ответа JSON Любой (JSON, XML, HTML, etc.)

Заключение

GraphQL – это язык запросов с открытым исходным кодом и среда выполнения для API. GraphQL был создан разработчиками Facebook для решения различных проблем, возникающих с традиционными REST API, таких как избыточная / недостаточная выборка данных и неэффективные сетевые запросы, путем создания декларативного языка запросов для API, управляемого клиентом.

Хотя GraphQL не является взаимозаменяемой концепцией с REST, они оба описывают разные способы управления обменом данными между клиентом и сервером. Из этой статьи вы узнали, что такое GraphQL, ключевые различия и сходства между GraphQL и REST, а также как сервер GraphQL предоставляет данные клиенту.