Вашему внимаю предлагаю перевод статьи Sacha Greif "Что же такое этот GraphQL?"
Если вы такой же, как и я, вы обычно проходите через три этапа, когда узнаёте о новой технологии:
- Отрицание Ещё одна JavaScript библиотека?! Зачем? У меня уже есть jQuery!
- Интерес Хм, наверное мне следует взглянуть на эту библиотеку...
- Паника Помогите! Мне нужно изучить эту библиотеку прямо сейчас, иначе мои знания устареют!
Есть одна хитрость для поддержания благоразумия в эпоху быстроразвивающихся технологий: изучать новые вещи между вторым и третьим этапом, как только интерес задет, но пока технология ещё не распространена повсеместно.
Именно поэтому сейчас самое время узнать, что же такое этот GraphQL, о котором вы повсюду слышите.
Основы
В двух словах, GraphQL это синтаксис, который описывает как запрашивать данные, и, в основном, используется клиентом для загрузки данных с сервера. GraphQL имеет три основные характеристики:
- Позволяет клиенту точно указать, какие данные ему нужны.
- Облегчает агрегацию данных из нескольких источников.
- Использует систему типов для описания данных.
Так с чего же начать изучение GraphQL? Как это выглядит на практике? Как начать его использовать? Читайте дальше чтобы узнать!
Задача
GraphQL был разработан в большом старом Facebook, но даже гораздо более простые приложения могут столкнуться с ограничениями традиционных REST API интерфейсов.
Например представьте, что вам нужно отобразить список записей
(posts
), и под каждым опубликовать список лайков
(likes
), включая имена пользователей и аватары. На самом деле, это не сложно, вы просто измените API posts
так, чтобы оно содержало массив likes
, в котором будут объекты-пользователи.
Но затем, при разработке мобильного приложения, оказалось что из-за загрузки дополнительных данных приложение работает медленнее. Так что вам теперь нужно два endpoint, один возвращающий записи с лайками, а другой без них.
Добавим ещё один фактор: оказывается, записи хранятся в базе данных MySQL, а лайки в Redis! Что же теперь делать?!
Экстраполируйте этот сценарий на то множество источников данных и клиентских API, с которыми имеет дело Facebook, и вы поймёте почему старый добрый REST API достиг своего предела.
Решение
Facebook придумал концептуально простое решение: вместо того, чтобы иметь множество "глупых" endpoint, лучше иметь один "умный" endpoint, который будет способен работать со сложными запросами и придавать данным такую форму, какую запрашивает клиент.
Фактически, слой GraphQL находится между клиентом и одним или несколькими источниками данных; он принимает запросы клиентов и возвращает необходимые данные в соответствии с переданными инструкциями. Запутаны? Время метафор!
Пользоваться старой REST-моделью это как заказывать пиццу, затем заказывать доставку продуктов, а затем звонить в химчистку, чтобы забрать одежду. Три магазина – три телефонных звонка.
GraphQL похож на личного помощника: вы можете передать ему адреса всех трех мест, а затем просто запрашивать то, что вам нужно («принеси мне мою одежду, большую пиццу и два десятка яиц») и ждать их получения.
Другими словами, GraphQL это стандартный язык для разговора с этим волшебным личным помощником.
Согласно Google Images, типичный личный помощник это пришелец с восемью руками
На практике GraphQL API построен на трёх основных строительных блоках: на схеме (schema), запросах (queries) и распознавателях (resolvers).
Запросы (queries)
(query и request одинаково переводится как "запрос". Далее будет подразумеваться query, если не указано иначе – прим. пер.)
Когда вы о чём-то просите вашего персонального помощника, вы выполняете запрос. Это выглядит примерно так:
query {
stuff
}
Мы объявляем новый запрос при помощи ключевого слова query
, также спрашивая про поле stuff
. Самое замечательное в запросах GraphQL является то, что они поддерживают вложенные поля, так что мы можем пойти на один уровень глубже:
query {
stuff {
eggs
shirt
pizza
}
}
Как можно заметить, клиенту при формировании запроса не нужно знать откуда поступают данные. Он просто спрашивает о них, а сервер GraphQL заботится об остальном.
Также стоит отметить, что поля запроса могут быть массивами. Например вот общий шаблон запроса списка сообщений:
query {
posts { # это массив
title
body
author { # мы может пойти глубже
name
avatarUrl
profileUrl
}
}
}
Поля запроса также могут содержать аргументы. Например, если необходимо отобразить конкретный пост, можно добавить аргумент id
к полю post
:
query {
post(id: "123foo"){
title
body
author{
name
avatarUrl
profileUrl
}
}
}
Наконец, если нужно сделать аргумент id
динамическим, можно определить переменную, а затем использовать её в запросе (обратите внимание, также мы сделали запрос именованным):
query getMyPost($id: String) {
post(id: $id){
title
body
author{
name
avatarUrl
profileUrl
}
}
}
Хороший способ попробовать все это на практике – использовать GraphQL API Explorer от GitHub. Например, давайте попробуем выполнить следующий запрос:
query {
repository(owner: "graphql", name: "graphql-js"){
name
description
}
}
GraphQL и автодополнение в действии
Обратите внимание, когда вы вводите имя поля, IDE автоматически предлагает вам возможные имена полей, полученные при помощи GraphQL API. Ловко!
Анатомия запросов GraphQL (англ)
Вы можете узнать больше о запросах GraphQL в отличной статье "Анатомия запросов GraphQL" (англ).
Распознаватели (resolvers)
Даже самый лучший в мире личный помощник не сможет принести ваши вещи из химчистки если вы не дадите ему адрес.
Подобным образом, сервер GraphQL не может знать что делать с входящим запросом, если ему не объяснить при помощи распознавателя (resolver).
Используя распознаватель GraphQL понимает, как и где получить данные, соответствующие запрашиваемому полю. К примеру, распознаватель для поля запись может выглядеть вот так (используя генератор схемы (schema) из набора Apollo GraphQL-Tools):
Query: {
post(root, args) {
return Posts.find({ id: args.id });
}
}
Мы помещаем наш распознаватель в раздел Query
потому что мы хотим получать запись
(post
) в корне ответа. Но также мы можем создать распознаватели для подполей, как например для поля author
:
Query: {
post(root, args) {
return Posts.find({ id: args.id });
}
},
Post: {
author(post) {
return Users.find({ id: post.authorId})
}
}
Обратите внимание что ваши распознаватели не ограничены в количестве возвращаемых объектов. К примеру, вы захотите добавить поле commentsCount
к объекту Post
:
Post: {
author(post) {
return Users.find({ id: post.authorId})
},
commentsCount(post) {
return Comments.find({ postId: post.id}).count()
}
}
Ключевое понятие здесь то, что схема запроса GraphQL и структура вашей базы данных никак не связаны. Другими словами, в базе данных может не существовать полей author
или commentsCount
, но мы можем "симулировать" их благодаря силе распознавателей.
Как было показано выше, вы можете писать любой код внутри распознавателя. Так что вы можете изменять содержимое базы данных; такие распознаватели называют изменяющими (mutation).
Схема (schema)
Все это становится возможным благодаря типизированной схеме данных GraphQL. Цель этой статьи дать скорее краткий обзор, чем исчерпывающее введение, так что в этом разделе не будет подробностей.
Я призываю вас заглянуть в документацию GraphQL (англ), если вы хотите узнать больше.
Часто задаваемые вопросы
Сделаем перерыв, чтобы ответить на несколько общих вопросов.
Эй, вы там, на задних рядах. Да вы. Я вижу, вы хотите что-то спросить. Идите вперед, не стесняйтесь!
Что общего у GraphQL и графовых баз данных?
Ничего общего. На самом деле, GraphQL не имеет ничего общего с графовыми БД типа Neo4j. Часть "Graph" отражает идею получения контента, проходя сквозь граф API, используя поля и подполя; часть "QL" расшифровывается как "query language" – "язык запросов".
Меня полностью устраивает REST, зачем мне переходить на GraphQL?
Если вы не достигли болевых точек REST API, решением которых является GraphQL, то можете не волноваться.
Использование GraphQL поверх REST вероятнее всего не заставит вас производить какие-то сложные изменения в остальном API и ломать накопившийся пользовательский опыт, так что переход не будет вопросом жизни и смерти в любом случае. Так что определенно стоит попробовать GraphQL в небольшой части проекта, если это возможно.
Могу ли я использовать GraphQL без React/Relay/имя_библиотеки?
Конечно! GraphQL это только спецификация, вы можете использовать его с любой библиотекой на любой платформе, используя готовый клиент (к примеру, у Apollo есть клиенты для web, iOS, Angular и другие) или вручную отправляя запросы на сервер GraphQL.
GraphQL был создан Facebook, а я не доверяю Facebook.
Ещё раз, GraphQL является всего лишь спецификацией, это значит что вы можете использовать его не используя ни одной строки кода, написанной Facebook.
Наличие поддержки Facebook это безусловно хороший плюс для экосистемы GraphQL. Но на данный момент сообщество достаточно большое чтобы поддерживать GraphQL даже если Facebook перестанет его использовать.
Как-то "позволить клиенту просить о тех данных, которые ему нужны" не выглядит безопасным
Так как вы пишете свои распознаватели, вы можете разрешать любые проблемы безопасности на этом уровне.
К примеру, если вы позволите клиенту использовать параметр limit
для указания количества документов, которые он запрашивает, вы скорее всего захотите контролировать это число для избежания атак типа "отказ в обслуживании" когда клиент будет запрашивать миллионы документов снова и снова.
Так что же нужно чтобы начать?
На самом деле, необходимо всего два компонента чтобы начать:
- Сервер GraphQL для обработки запросов к API
- Клиент GraphQL, который будет подключаться к endpoint.
Теперь, когда вы понимаете как работает GraphQL, можно поговорить о главных игроках в этой области.
Серверы GraphQL
Первое что вам нужно для работы, это сервер GraphQL. Сам GraphQL это просто спецификация, так что двери открыты для конкурирующих реализаций.
GraphQL-JS (Node)
Это ссылка на оригинальную реализацию спецификации GraphQL. Вы можете использовать её с express-graphql для создания своего сервера API (англ).
GraphQL-Server (Node)
Команда Apollo имеет свою собственную реализацию GraphQL-сервера. Она ещё не настолько полна как оригинал, но очень хорошо документирована, хорошо поддерживается и быстро развивается.
Другие платформы
На официальном сайте есть список реализаций спецификации GraphQL для различных платформ (PHP, Ruby и другие).
Клиенты GraphQL
Конечно вы можете работать с API GraphQL напрямую, но специальная клиентская библиотека определённо может сделать вашу жизнь проще.
Relay
Relay это собственный инструментарий Facebook. Он создавался с учётом потребностей Facebook и может быть немного избыточным для большинства пользователей.
Клиент Apollo
Быстро занял своё место новый участник в этой области — Apollo. Типичный клиент состоит из двух частей:
- Apollo-client, позволяющий выполнять запросы GraphQL в браузере (также есть расширение для DevTools)
- Коннектор для frontend-фреймворка (React-Apollo, Angular-Apollo и другие)
По умолчанию Apollo-client сохраняет данных используя Redux, который сам является достаточно авторитетной библиотекой управления состоянием с богатой экосистемой.
Расширение Apollo для Chrome DevTools
Приложения с открытым исходным кодом
Несмотря на то, что GraphQL это достаточно новая концепция, уже есть некоторые перспективные приложения с открытым исходным кодом, которые используют её.
VulcanJS
Я (автор оригинальной статьи — прим. пер.) являюсь ведущим разработчиком VulcanJS. Я создал его чтобы дать людям возможность попробовать силу стека React/GraphQL без необходимости писать много шаблонного кода. Вы можете воспринимать его как "Rails для современной web-экосистемы" потому что он позволяет создавать CRUD-приложения (клон Instagram например) в течение нескольких часов.
Gatsby
Gatsby это генератор статических сайтов для React, который начиная с версии 1.0 также использует GraphQL. Несмотря на то, что это можно показаться странным сочетанием на первый взгляд, это на самом деле довольно мощная идея. В процессе сборки Gatsby может извлекать данные из нескольких GraphQL API, затем используя их для создания полностью статического клиентского React-приложения.
Другие инструменты для работы с GraphQL
GraphiQL
GraphiQL это очень удобная браузерная IDE для создания и выполнения запросов к endpoint-ам GraphQL.
DataLoader
Из-за вложенной природы запросов GraphQL, один запрос может легко вызывать десятки обращений к базе данных. Для снижения нагрузки вы можете использовать инструменты кеширования наподобие разработанной Facebook библиотеке DataLoader.
Create GraphQL Server
Create GraphQL Server это консольная программа, позволяющая легко и быстро сгенерировать сервер на базе Node, использующий базу данных Mongo.
GraphQL-up
Аналогично Create GraphQL Server, GraphQL-up позволяет быстро создать GraphQL backend, но на базе сервиса Graphcool.
Сервисы GraphQL
Наконец, есть целый ряд компаний, предоставляющих "GraphQL-backend-как-сервис"; они сами позаботятся о серверной части для вас, и это может быть хорошим способом окунуться в экосистему GraphQL.
Graphcool
Гибкая backend-платформа, объединяющая GraphQL и AWS Lambda, имеющая бесплатный тарифный план для разработки.
Scaphold
Другой GraphQL-backend-как-сервис с бесплатным тарифным планом. Он предлагает много функций, подобных Graphcool.
Уже есть немало ресурсов по GraphQL.
(Также предлагайте ресурсы на русском языке в комментариях – прим. пер.)
GraphQL.org (англ)
На официальном сайте GraphQL есть замечательная документация чтобы начать.
LearnGraphQL (англ)
LearnGraphQL это интерактивный курс, созданный в компании Kadira.
LearnApollo (англ)
Хорошее продолжение LearnGraphQL, LearnApollo это бесплатный курс, созданный Graphcool.
Блог Apollo (англ)
Блог Apollo имеет массу подробных хорошо написанных постов о Apollo и GraphQL в целом.
GraphQL Weekly (англ)
Информационная рассылка о GraphQL, курируемая командой Graphcool.
Hashbang Weekly (англ)
Еще одна большая новостная рассылка, которая помимо GraphQL также охватывает React и Meteor.
Freecom (англ)
Серия руководств, описывающая как создать клон Интерком с помощью GraphQL.
Awesome GraphQL (англ)
Довольно исчерпывающий перечень ссылок и ресурсов по GraphQL.
Как же вы можете применить вновь приобретенные знания о GraphQL на практике? Вот несколько рецептов, которые можно попробовать:
Apollo + Graphcool + Next.js
Если вы уже знакомы с Next.js и React, этот пример позволит вам настроить GraphQL endpoint при помощи Graphcool и затем отправлять ей запросы при помощи Apollo.
VulcanJS
Учебник Vulcan (англ) поможет вам создать простой слой данных GraphQL на сервере и на клиенте. Поскольку Vulcan является платформой "все-в-одном", это хороший способ начать работу без каких-либо настроек. Если вам нужна помощь, не стесняйтесь обратиться в наш канал Slack (англ)!
Учебник GraphQL & React
В блоге Chroma есть руководство из шести частей (англ) по созданию приложения React/GraphQL используя компоненто-ориентированный подход к разработке.
Заключение
GraphQL поначалу может показаться сложным, потому что это технология, которая затрагивает многие области современной разработки. Но уделив время чтобы понять основные концепции, я думаю вы поймёте что многое из этого имеет смысл.
Решите ли вы использовать это или нет, я считаю что стоит потратить время чтобы ознакомиться с GraphQL. Все больше и больше компаний и структур начинают использовать его, и он вполне может в течение следующих нескольких лет стать одним из ключевых строительных блоков в веб-разработке.
Согласны? Не согласны? Вопросы? Дайте мне знать, здесь в комментариях.
Автор: aliksend