что 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 их разделяет.Открытый исходный код:
- Стандарт языка:Соглашение Open Web Foundation Agreement (OWFa) версии 1.0
- GraphQL.js, клиентский инструмент Relay: протокол MIT
Давайте рассмотрим функции 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