GraphQL

GraphQL — язык запросов и манипулирования данными, позволяющий явно указывать, какие данные требуется получить («декларативное получение данных») или изменить. Сервер GraphQL может обрабатывать запрос клиента, используя данные из различных источников, и представлять результат в виде единого графа. Язык не привязан к какой-либо конкретной базе данных или механизму хранения. Существует несколько открытых исполняемых сред для GraphQL.

Что важно знать
GraphQL
Тип graph query language
Автор Meta Platforms
Разработчик The GraphQL Foundation
Написана на реализации на Java, JavaScript, Ruby, Scala и других языках
Первый выпуск 14 сентября 2015
Последняя версия October 2021
Репозиторий github.com/graphql/graph…
Сайт graphql.org

История

Facebook начал разработку GraphQL в 2012 году и опубликовал черновой стандарт и эталонную реализацию с открытым исходным кодом в 2015 году[1]. В 2018 году проект GraphQL был передан в специально созданный фонд GraphQL Foundation, который управляется некоммерческой Linux Foundation[2].[3]

9 февраля 2018 года язык определения схемы GraphQL был включён в спецификацию[4].

Многие крупные открытые API внедрили GraphQL в качестве основного интерфейса доступа. Среди них публичные API Facebook, GitHub, Yelp, Shopify, Google Directions API и другие[5].[6]

Архитектура и принципы работы

GraphQL поддерживает чтение, изменение (мутация) и подписку на изменения данных (режим реального времени, часто реализуется через WebSocket)[7]. Сервис GraphQL создаётся путём описания типов с их полями и предоставления функций для получения данных для каждого поля. Эти типы и поля формируют так называемое описание схемы (schema definition). Функции, которые возвращают и сопоставляют данные, называются резолверами[8].

После валидации против схемы, запрос GraphQL исполняется сервером. Результат возвращается в структуре, повторяющей форму исходного запроса, обычно в виде JSON[9].

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

undefined

С помощью GraphQL предметная область моделируется в виде графа путём определения схемы: в ней задаются различные типы узлов и их отношения друг с другом[10].

Система типов определяет, какие данные могут быть запрошены через API. Совокупность таких возможностей называется схемой сервиса, и клиенты могут использовать схему для отправки предсказуемых запросов[11].

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

Поля по умолчанию допускают отсутствие значения (nullable), а восклицательный знак после типа делает поле обязательным (not-null). Для обозначения списка тип оборачивается в квадратные скобки, например: authors: [String][12].

type Query {
  currentUser: User
}

type User {
  id: ID!
  name: String!
}

Запросы (queries)

Запрос в GraphQL явно определяет форму (структуру) требуемых данных.

query CurrentUser {
  currentUser {
    name
    age
  }
}

После проверки и выполнения сервером данные возвращаются в той же структуре.

{
  "currentUser": {
    "name": "John Doe",
    "age": 23
  }
}

Мутации (mutations)

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

mutation CreateUser($name: String!, $age: Int!) {
  createUser(userName: $name, age: $age) {
    name
    age
  }
}

Переменные передаются объектом, содержащим поля с соответствующими именами:

{
  "name": "Han Solo",
  "age": 42
}

После выполнения операции сервер возвращает данные в описанной структуре:

{
  "data": {
    "createUser": {
      "name": "Han Solo",
      "age": 42
    }
  }
}

Подписки (subscriptions)

GraphQL также поддерживает режим подписки: сервер может отправлять клиенту актуальные изменения данных. Как и в других операциях, клиент определяет структуру необходимых данных при каждом обновлении.

subscription {
  newPerson {
    name
    age
  }
}

При выполнении соответствующей мутации подписанные клиенты получают новые данные в указанном формате:

{
  "newPerson": {
    "name": "Jane",
    "age": 23
  }
}

Версионирование

Хотя ничто не мешает внедрять версионирование GraphQL API так же, как и других API, сам подход GraphQL акцентируется на непрерывном развитии схемы без выделения версий[13].

Встроенная директива @deprecated используется для пометки устаревших полей и значений в определении схемы[12].

GraphQL возвращает только явно запрошенные поля, поэтому новые возможности легко добавлять новыми типами или полями, избегая критических изменений. На практике сложился подход его использования без версионности[13].

Сравнение с другими языками запросов

GraphQL не предоставляет полноценного графового языка запросов, как SPARQL, или диалектов SQL с поддержкой транзитивного замыкания. Например, интерфейс GraphQL, возвращающий родителей персоны, не позволит получить в одном запросе всех предков.

Тестирование

GraphQL API могут тестироваться вручную либо с помощью автоматизированных инструментов, которые выполняют запросы и проверяют корректность результатов. Также возможна автоматическая генерация тестов[14]. Благодаря типизированной схеме и возможностям интроспекции тестовые запросы можно генерировать поисковыми методами[15].

Среди популярных инструментов для тестирования реализации GraphQL — Postman, GraphiQL, Apollo Studio, GraphQL Hive, GraphQL Editor и Step CI[16]. Также существует сервис Hive Laboratory[17].

Примечания

Ссылки