Предварительное исследование GraphQL — ориентированного на будущее API и его экосистемы

Node.js задняя часть внешний интерфейс API GraphQL Facebook

что GraphQL ? Первое знакомство с этим термином напоминает язык запросов к базе данных SQL. Но по сути это две совершенно разные вещи, в официальной документации GraphQL определяется так:

GraphQL is a query language for your API, and a server-side runtime for executing queries by using a type system you define for your data.

То есть GraphQL — это и язык запросов API, и его реализация на стороне сервера. Но GraphQL предназначен не только для создания языка запросов, подобного базе данных, в области API, его рождение больше связано с изменением мышления в дизайне API.

Загадка шаблона REST

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

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

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

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

И теперь широко используется в области APIОТДЫХА шаблон, в условиях вышеупомянутого все более сложного взаимодействия между клиентом и сервером постепенно возникла проблема:

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

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

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

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

Решения GraphQL

Столкнувшись с указанными выше недостатками паттерна REST, Facebook предложил свое решение — GraphQL:

Как упоминалось ранее, GraphQL — это не только язык запросов API, но и его серверная реализация, поэтому сам GraphQL также состоит из двух частей, Facebook их разделяет.Открытый исходный код:

Давайте рассмотрим функции GraphQL один за другим:

Декларативное извлечение данных

Как показано на рисунке ниже, декларативный запрос данных обеспечивает точный возврат интерфейса.Сервер вернет данные JSON с той же структурой в формате запроса данных, что действительно заботится о гибкости клиента:

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

Сервис предоставляет только один слой GraphQL.

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

Независимость от транспортного уровня и технологии базы данных

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

Обзор доступа к GraphQL

Поскольку GraphQL имеет много преимуществ, как получить к нему доступ? В общем, есть три способа доступа:

Служба GraphQL напрямую подключена к базе данных

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

Слой GraphQL, который интегрирует существующие сервисы

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

Гибридная модель прямой базы данных и сервисов интеграции

Смесь первых двух способов:

Анализ основных концепций GraphQL

Основной особенностью GraphQL является декларативная схема API.Схема GraphQL представляет собой декларативную спецификацию запроса (которую можно рассматривать как протокол запроса между сервером и клиентом), которая в основном состоит из двух частей:

  • система типов
  • Синтаксис записи: SDL (язык определения представления)

Система типов GraphQL включает в себя некоторые распространенные типы данных в различных языках программирования.Подробности см.СпецификацияК пониманию.

Далее краткое введение в синтаксис SDL GraphQL:

Определить схему API

Определение пользовательских типов в основном выполняется на стороне сервера, синтаксис следующий:

type 类型名 {
    字段名: 类型
}

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

type User {
    id: Int!
    name: String
}

Затем определите несколько схем API для манипулирования данными:

type Query { // 基本查询 Schema
    user(id: Int!): User // 传入一个 id ,返回具体用户
}

type Mutation { // 操作数据的 Schema
    createUser( // 传入用户名自动创建一个用户
        name: String
    ): User
}

type Subscription { // 监听数据变更的 Schema
    userChanged: User
}

манипуляция данными

С помощью этих определенных схем API мы можем инициировать операции с данными здесь. Операции с данными GraphQL также делятся наQuery, Mutation, SubscriptionТри типа. просто говоря,QueryЭто основной запрос для получения данных;MutationПоддерживает такие операции, как добавление, удаление и изменение данных;SubscriptionОн используется для отслеживания изменений данных и передачи измененных сообщений подписчикам по таким протоколам, как Websocket.

На основе пользовательской схемы, определенной выше, мы можем написать следующие операции с данными:

query {
  user(id:3) { // 查询用户 id 为3的用户
    name
  }
}

mutation {
  createUser(name: "Tom") { // 新增一个名为 "Tom" 的用户
    name
    id
  }
}

subscription {
  userChanged { // 监听用户数据变动
    name
    id
  }
}

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

{
  "data": {
    "createUser": {
      "name": "Tom",
      "id": 9
    }
  }
}

Экосистема GraphQL

С помощью схемы API мы можем указать как функциональность API, так и то, как клиенты запрашивают данные. Но это всего лишь спецификация, и как эта спецификация GraphQL реализована? Далее мы представим «экосистему» ​​разработки приложений GraphQL вокруг сервера, клиента и инструментов отладки.

Реализация сервера

На стороне сервера сервер GraphQL может быть реализован на любом языке, который можно использовать для создания веб-сервера. В дополнение к JavaScript, Ruby, Python, Scala, Java, Clojure, Go и .NET имеют реализации для справки.

Базовый алгоритм выполнения запроса на стороне сервера также очень прост: запрос проходит поле за полем и выполняет распознаватель для каждого поля для обработки операций с данными. На рисунке ниже показан пример:

В крайнем левом углу находится запрос GraphQL, который запрашивает идентификатор'abc'Название и содержание всех статей авторские. На среднем рисунке показан тип данных, соответствующий каждому полю запроса, а затем вы можете увидеть процесс синтаксического анализа каждого поля в крайнем правом углу: во-первых, идентификатор запроса'abc'Автор , а затем получить все его статьи от автора; и, поскольку статья представляет собой список, в конечном итоге мы должны пройти по этому списку, чтобы получить заголовок и содержание, соответствующие каждой статье.

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

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

Обсуждали выше базовую реализацию идеи сервера GraphQL, а для реализации Node.js, на основе моего более раннего примера схемы API напишем простуюDemo, читатели могут понять, как реализован и используется сервер GraphQL.

Реализация клиента

Общие клиентские библиотеки GraphQL:

  • Relay: официальный клиент Facebook GraphQL, который значительно оптимизирует производительность, но доступен только в Интернете.
  • Apollo: проект сообщества с открытым исходным кодом, направленный на создание мощных и гибких клиентов GraphQL для всех платформ разработки (Web, Android, iOS, React Native и т. д.).

Что касается того, как использовать эти две клиентские библиотеки, вы можете обратиться к официальной документации, которая не будет здесь повторяться. Для входа Аполлона, Full-stack React + GraphQL Tutorial В этой статье представлен простой пример, рекомендуется попробовать его и создать свое первое приложение GraphQL.

Инструменты разработки

GraphQL имеет большое количество практических инструментов разработки, которые в основном реализованы на основе запросов самоанализа. Так называемый запрос самоанализа относится к запросу, который клиент запрашивает у сервера для получения информации о схеме API. Например, мы можем запросить__schemaи другие метаполя для получения полной информации о типе:

query {
  __schema {
    types {
      name // 获取根字段名
      fields {
        name // 获取字段名
      }
    }
  }
}

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

перед намиДемонстрация сервераИнструменты отладки на основе GraphiQL также представлены в виде промежуточного программного обеспечения.GraphQL PlayGround . После запуска демо вы можете получить доступlocalhost:3000/playgroundПопробуйте все запросы, перечисленные выше~

Проблемы с GraphQL

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

безопасный вопрос

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

Кроме того, оператор запроса, инициируемый каждый раз, также по существу отражает структуру документа запроса.Если злоумышленник перехватывает наш запрос и собирает воедино полное содержимое интерфейса, это не способствует безопасности интерфейса.

Перед лицом давления запросов мы можем смягчить его с помощью таких мер, как ограничение тока на стороне сервера и ограничение тока на стороне клиента. Конкретные меры по ограничению тока см.эта статья.

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

Возможности кэширования на стороне сервера

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

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

Суммировать

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

В то же время его активное сообщество и все более зрелая экосистема также доказывают, что это очень жизнеспособная технология.В настоящее время GraphQL используется в производственных средах многими компаниями (Facebook, GitHub, Twitter и т. д.) с большими перспективами развития.

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

Ref

официальная документация
[Перевод] Как использовать GraphQL