После многих лет борьбы с API на отдых, когда я впервые узнал о GraphQL и проблемах, которые он пытается решить, я не мог противостоять Tweeting точное название этой статьи.
Конечно, вернулся тогда, это была просто попытка, чтобы быть забавным, но сегодня я считаю, что забавный прогноз на самом деле происходит.
Пожалуйста, не интерпретируйте это неправильно. Я не собираюсь обвинять GraphQl «убийства» отдыха или что-то в этом роде. Остальные, вероятно, никогда не умрут, как XML никогда не делал. Я просто думаю, что Graphql сделает, чтобы отдохнуть, что Джосон сделал с XML.
Эта статья на самом деле не на 100% в пользу GraphQL. Существует очень важный раздел о стоимости гибкости GraphQl. С большой гибкостью приходит большая стоимость.
Я большой поклонник «всегда |». Начните с того, почему “, так что давайте сделаем это.
Таким образом: почему graphql?
3 самых важных задачи, которые GraphQL решает красиво:
- Необходимость делать несколько круглых поездок, чтобы получить данные, необходимые для вида : С GraphQL вы всегда можете получить все исходные данные, необходимые с помощью A одинокий круглая поездка на сервер. Чтобы сделать то же самое с API для отдыха, нам нужно ввести неструктурированные параметры и условия, которые трудно управлять и масштабироваться.
- Клиенты зависимости на серверах : С GraphQL клиент говорит на языке запроса, который: 1) устраняет необходимость в сервере для жесткого крепления формы или размера данных, а 2) Клиентами декурсионов с серверов. Это означает, что мы можем поддерживать и улучшать клиентов отдельно от серверов.
- Плохой опытный опыт работы в интернет-концерте : С GraphQL разработчики выражают требования к данным своих пользовательских интерфейсов с использованием декларативного языка. Они выражают что им нужны, не Как сделать это доступным. Существует плотная связь между тому, какие данные необходимы UI, и способ разработчика может выразить описание этих данных в GraphQL.
Эта статья подробно объяснит, как GraphQL решает все эти проблемы.
Прежде чем мы начнем, для тех из вас, еще не знакомых с GraphQL, давайте начнем с простых определений.
Что такое график?
Graphql – это язык Отказ Если мы преподаем GraphQL к программному приложению, это приложение сможет декларативно Сообщите любые требования к данным к службе поддержки данных, которые также говорят на GraphQL.
Чтобы научить службу данных говорить GraphQL, нам нужно реализовать Во время выполнения слой и разоблачить его клиентам, которые хотят общаться с сервисом. Подумайте об этом слое на стороне сервера как просто переводчик языка графаКкла или графиком, который представляет собой службу данных. GraphQL не является двигателем хранения, поэтому он не может быть самостоятельно. Вот почему мы не можем иметь сервер, который говорит просто GraphQL И нам нужно вместо этого реализовать во время выполнения перевода.
Этот слой, который можно записать на любом языке, определяет общую схему на основе графов для публикации Возможности Служба данных представляет собой. Клиентские приложения, которые говорят, что GraphQL могут запрашивать эту схему в его возможностях. Этот подход декуцирует клиентов от серверов и позволяет им обоим развиваться и масштабироваться самостоятельно.
Запрос GraphQL может быть либо Запрос (Читать операцию) или Мутация ( Пишите операцию). Для обоих случаев запрос представляет собой простую строку, которую служба GraphQL может интерпретировать, выполнять и разрешать с данными в указанном формате. Популярный формат ответа, который обычно используется для мобильных и веб-приложений JSON Отказ
Что такое график? (Версия объяснения-это – я-5)
GraphQL – это все о передаче данных. У вас есть клиент и сервер, и оба им нужно поговорить друг с другом. Клиент должен сообщить серверу, какие ему данные необходимо, и сервер должен выполнить требование этого клиента с фактическими данными. GraphQL шаги в середину этой связи.
Почему клиент не может просто общаться напрямую с сервером, вы спрашиваете? Это конечно может.
Есть несколько причин рассмотрения слоя GraphQL между клиентами и серверами. Один из этих причин, и, возможно, самый популярный, это Эффективность Отказ Клиент обычно должен задать сервер о несколько Ресурсы, и сервер обычно понимает, как ответить одним ресурсом. Таким образом, клиент заканчивается, что делает несколько круглых поездок на сервер, чтобы собрать все необходимые данные.
С GraphQL мы можем в основном сдвинуть этот многоуровневый сложность с несколькими запросами на серверную сторону и иметь дело с этим слоем GraphQL. Клиент задает один вопрос на графике и получает один ответ, который имеет именно то, что требует клиента.
Есть гораздо больше преимуществ для использования слоя GraphQL. Например, другая большая выгода передается с несколькими услугами. Когда у вас есть несколько клиентов, запрашивающих данные из нескольких услуг, слой графа в середине может упростить и стандартизировать эту связь. Хотя это не совсем точка против APIS-API – так как легко выполнить то же самое – это время выполнения GraphQL предлагает структурированный и стандартизированный способ сделать это.
Вместо того, чтобы клиент переходил на два разных служба данных напрямую (на скольжении выше), мы можем иметь этот клиент общаться с слоем GraphQL. Затем слой GraphQL будет выполнять связь с двумя различными службами данных. Вот как GraphQL сначала изолирует клиентов, чтобы общаться на нескольких языках
Компьютеры не достаточно умны, чтобы ответить на любые вопросы (по крайней мере, еще не), поэтому они должны где-то следовать алгоритм. Вот почему нам нужно определить схему времени выполнения графиков, и эта схема используется клиентами.
Схема в основном является документом возможностей, в котором есть список всех вопросов, которые клиент может задать слой графика. Существует некоторая гибкость в том, как использовать схему, потому что мы говорим о графе узлов здесь. Схема в основном представляет пределы того, что можно ответить слоем GraphQL.
Еще не понятно? Давайте назовем Graphql, что это на самом деле и просто есть: Замена для отдыха API. Так что позвольте мне ответить на вопрос, который вы, скорее всего, спрашиваете сейчас.
Что не так с аписом отдыха?
Самая большая проблема с API для отдыха – характер нескольких конечных точек. Это требуют, чтобы клиенты делали несколько круглых поездок, чтобы получить их данные.
Остальные API обычно представляют собой коллекцию конечных точек, где каждая конечная точка представляет ресурс. Таким образом, когда клиент нуждается в данных из нескольких ресурсов, ему необходимо выполнить несколько круглых поездок в API для отдыха, чтобы собрать необходимые им данные.
В API отдыха нет языка запроса клиента. Клиенты не имеют контроля над тем, какие данные сервер вернется. Там нет языка, через который они могут сделать это. Точнее, язык, доступный для клиентов, очень ограничен.
Например, Читать Остальные API конечные точки либо:
- Получить
/ResourceName– получить список всех записей из этого ресурса или - Получить
/ResourceName/RecentiD– Чтобы получить единственную запись, определенную этим идентификатором.
Клиент не может, например, указать, какой Поля выбрать для записи в этом ресурсе. Эта информация находится в самой службе API Остальной API, и служба API OST всегда будет возвращать все поля независимо от того, какие из них нужны клиент. Срок графов для этой проблемы входит чрезмерная выборка информации, которая не нужна. Это пустая трата сети и ресурсов памяти как для клиента, так и для сервера.
Еще одна большая проблема с API для отдыха – версия. Если вам нужно поддерживать несколько версий, это обычно означает новые конечные точки. Это приводит к большему количеству проблем при использовании и поддержании этих конечных точек, и это может быть причиной дублирования кода на сервере.
Упомянутые выше проблемы API-API, являются теми, которые специфики для того, что GraphQL пытается решить. Они, безусловно, не все проблемы отдыха API, и я не хочу попасть в то, что такое API для отдыха и нет. Я в основном говорю о популярном ресурсе-API-топ-точке. Каждый из этих API в конечном итоге превращается в смесь, которая имеет обычные конечные точки отдыха + пользовательские специальные конечные точки Ad-HOC, созданные по причинам эффективности. Это где GraphQL предлагает гораздо лучшую альтернативу.
Как GraphQL делает свою магию?
Есть много концепций и дизайнерских решений за GraphQL, но, вероятно, самые важные:
- Схема GraphQL – это сильно напечатанная схема. Чтобы создать схему GraphQL, мы определяем Поля которые имеют Типы Отказ Эти типы могут быть примитивными или обычаями, и все остальное в схеме требует типа. Эта система богатых типов позволяет делать богатые функции, такие как имеющие интроспективные API, и возможность создавать мощные инструменты для клиентов, так и для серверов.
- GraphQL говорит с данными как график, а данные естественным образом являются графиком. Если вам нужно представить любые данные, правильная структура представляет собой график. Время выполнения GraphQL позволяет нам представлять наши данные с графиком API, который соответствует естественной форме диаграммы этих данных.
- GraphQL имеет декларативный характер для выражения требований к данным. GraphQL предоставляет клиентам декларативный язык для них, чтобы выразить свои потребности в данных. Эта декларативная природа создает умственную модель вокруг использования языка GraphQL, который близко к тому, как мы думаем о требованиях к данным на английском языке, и он делает работу с API GraphQL намного проще, чем альтернативы.
Последняя концепция заключается в том, почему я лично верю, что graphql – это чейнджер игры.
Это все концепции высокого уровня. Давайте воспользуемся более подробно.
Чтобы решить множественную проблему с круглой поездкой, Graphql делает реагированный сервер всего одной конечной точкой. В основном, Graphql принимает собственную идею конечной точки в экстремальную и просто делает весь сервер одной пользовательской конечной точкой, которая может ответить на все вопросы данных.
Другая большая концепция, которая идет с этой единственной концепцией конечной точки, является богатым языком запроса клиента, который необходим для работы с этой пользовательской одной конечной точкой. Без языка запроса клиента одна конечная точка бесполезна. Нужен язык для обработки пользовательской запроса и отвечать с помощью данных для этой пользовательской запроса.
Наличие языка запроса клиента означает, что клиенты будут контролироваться. Они могут просить именно то, что им нужно, и сервер ответит именно то, что они просят. Это решает проблему с чрезмерной выборкой.
Когда дело доходит до версий, Graphql имеет интересный взять на это. Версию можно избежать всех вместе. По сути, мы можем просто добавить новые Поля Не удаляя старые, потому что у нас есть график, и мы можем гибко выращивать график, добавив больше узлов. Таким образом, мы можем оставить пути на графике для старых API и представить новые без маркировки их как новых версий. API просто растет.
Это особенно важно для мобильных клиентов, потому что мы не можем контролировать версию API, которые они используют. После установки мобильное приложение может продолжать использовать эту же старую версию API в течение многих лет. В Интернете легко контролировать версию API, потому что мы просто нажимаем новый код. Для мобильных приложений это намного сложнее сделать.
Пока не совсем убежден? Как насчет того, чтобы мы делаем однозначное сравнение между GraphQL и отдыхом с фактическим примером?
Redful apis vs graphql apis – Пример
Давайте представим, что мы являемся разработчиками, ответственными за создание блестящего нового пользовательского интерфейса для представления фильмов и персонажей звездных войн.
Первый пользовательский интерфейс, который нам поручил построить, просто: представление, чтобы показать информацию о человеке одиноких звездных войн. Например, Дарт Вейдер, и все фильмы, в котором этот человек появился. Эта точка зрения должна отображать имя человека, год рождения, имя планеты и названия всех фильмов, в которых они появились.
Так же просто, как это звучит, мы на самом деле имеем дело с 3 разными ресурсами здесь: человек, планета и фильм. Отношения между этими ресурсами просты, и любой может угадать форму данных здесь. Объект человека принадлежит одному объекту планеты, и он будет иметь один или несколько объектов фильмов.
Данные JSON для этого UI могут быть что-то вроде:
{
"data":{
"person":{
"name":"Darth Vader",
"birthYear":"41.9BBY",
"planet":{
"name":"Tatooine"
},
"films":[
{
"title":"A New Hope"
},
{
"title":"The Empire Strikes Back"
},
{
"title":"Return of the Jedi"
},
{
"title":"Revenge of the Sith"
}
]
}
}
}Предполагая, что служба данных дала нам эту точную структуру для данных, вот один из возможных способов представлять свое представление с React.js:
// The Container Component:
// The PersonProfile Component:Name: {person.name}Birth Year: {person.birthYear}Planet: {person.planet.name}Films: {person.films.map(film => film.title)}Это простой пример, и хотя наш опыт со звездными войнами, возможно, помог нам здесь немного, отношения между UI и данные очень ясны. Уэй использовал все «ключи» из объекта Data Data Data.
Давайте теперь посмотрим, как мы можем попросить эти данные, используя reзов API.
Нам нужна информация одинарного человека, и предполагая, что мы знаем ID этого человека, ожидается, что redful API будет раскрыть эту информацию как:
GET - /people/{id}Этот запрос даст нам имя, рождаемость и другую информацию о человеке. Хороший спокойный API также даст нам удостоверение личности планеты этого человека и множество идентификаторов для всех фильмов, которыми этот человек появился.
Ответ JSON на этот запрос может быть что-то вроде:
{ "name": "Darth Vader", "birthYear": "41.9BBY", "planetId": 1 "filmIds": [1, 2, 3, 6], *** other information we do not need ***}Затем, чтобы прочитать имя планеты, мы спрашиваем:
GET - /planets/1
И прочитать названия фильмов, мы спрашиваем:
GET - /films/1GET - /films/2GET - /films/3GET - /films/6
Как только у нас есть все 6 ответов с сервера, мы можем объединить их, чтобы удовлетворить данные, необходимые по нашему представлению.
Помимо того, что нам пришлось сделать 6 круглых поездок, чтобы удовлетворить простые данные о простых интерфейсах, наш подход здесь был обязательным. Мы дали инструкции для Как Чтобы получить данные и Как обработать его, чтобы сделать его готовым к мнению.
Вы можете попробовать это сами, если хотите увидеть, что я имею в виду. Данные Star Wars имеют REStful API, в настоящее время размещенные в настоящее время http://swapi.co/ Отказ Продолжайте и попытайтесь построить наши данные объекта. Ключи могут быть немного по-другому, но конечные точки API будут одинаковыми. Вам нужно будет делать ровно 6 вызовов API. Кроме того, вам придется перевернуть информацию о том, что представление не нужно.
Конечно, это всего лишь одна реализация восстановленного API для этих данных. Там могут быть лучшие реализации, которые облегчат этот взгляд для реализации. Например, если API-сервер реализовал вложенные ресурсы и понял связь между человеком и пленкой, мы могли бы прочитать данные фильма с:
GET - /people/{id}/filmsТем не менее, чистый сервер API-API, скорее всего, не будет реализовать, и нам нужно было бы попросить наших инженеров Backend создавать эту пользовательскую конечную точку для нас. Это реальность масштабирования спокойного API – мы просто добавляем пользовательские конечные точки для эффективного удовлетворения растущих потребностей клиентов. Управление пользовательскими конечными точками, как это сложно.
Давайте теперь посмотрим на подход GraphQL. GraphQL на сервере охватывает идею пользовательских конечных точек и принимает ее к своей крайности. Сервер будет просто одной конечной точкой, а канал не имеет значения. Если мы сделаем это через http, метод HTTP, безусловно, тоже не имеет значения. Давайте предположим, что у нас есть одна конечная точка GraphQL, выставленная на http на /graphql. Отказ
Поскольку мы хотим попросить данные, которые нам нужны в одном туристическом путешествии, нам понадобится способ выразить наши полные потребности в данных для сервера. Мы делаем это с помощью запроса GraphQL:
GET or POST - /graphql?query={...}Запрос GraphQL – это просто строка, но ему придется включать все куски данных, которые нам нужны. Это где приходит декларативная власть.
На английском, вот как мы объявляем наши требования к данным: Нам нужно имя человека, год рождения, имя планеты и названия всех своих фильмов Отказ В GraphQL это переводит:
{ person(ID: ...) { name, birthYear, planet { name }, films { title } }}Прочитайте English-requested требования еще раз и сравните его с запросом GraphQL. Это так близко, как может получить. Теперь сравните этот запрос GraphQL с оригинальными данными JSON, с которыми мы начали. Запрос GraphQL является точной структурой данных JSON, за исключением без всех деталей «значений». Если мы думаем об этом с точки зрения отношения ответа на вопрос, вопрос является утверждением ответа без части ответа.
Если утверждение ответа:
Хорошее представление вопроса одинаковое утверждение без части ответа:
Те же отношения применяются к запросу GraphQL. Возьмите ответ JSON, удалите все детали «Ответ» (которые являются значениями), и вы в конечном итоге с помощью запроса GraphQL, очень подходящим для представления вопроса об этом ответе JSON.
Теперь сравните запрос GRAPHQL с декларативным реагированным интерфейсом, который мы определены для данных. Все в запросе GraphQL используется в пользовательском интерфейсе, и в запросе GraphQL появляется все, что используется в UI.
Это великая умственная модель графаQL. UI знает точные данные, необходимые и извлекать это требование довольно легко. Работа с запросом GraphQL – это просто задача извлечения того, что используется в качестве переменных непосредственно из пользовательского интерфейса.
Если мы инвертируем эту модель, она все равно удерживает питание. Если у нас есть запрос GraphQL, мы точно знаем, как использовать его ответ в интерфейсе UI, потому что запрос будет такой же «структурой», как ответ. Нам не нужно проверять ответ, чтобы знать, как его использовать, и нам не нужна какая-либо документация о API. Это все встроенно.
Данные звездных войн имеют API GraphQL, размещенные в https://github.com/graphql/swapigraphql . Отказ Продолжайте и попытайтесь построить наши данные объекта. Есть несколько незначительных различий, которые мы объясним позже, но вот официальный запрос, который вы можете использовать против этого API, чтобы прочитать наши требования к данным для представления (с дартом Vader в качестве примера):
{ person(personID: 4) { name, birthYear, homeworld { name }, filmConnection { films { title } } }}Эта просьба дает нам структуру реагирования, очень близко к использованию нашего представления, и помните, мы получаем все эти данные в единую круговую поездку.
Стоимость гибкости GraphQL
Идеальные решения являются сказками. С гибкостью GraphQL представляется, дверь открывается на некоторых ясных проблемах и проблемах.
Одной из важных угроз, которые GraphQL облегчает исчерпывание ресурсов (aka ronial of Services Attacks). Сервер GraphQL может быть атакован чрезмерно сложными запросами, которые потребляют все ресурсы сервера. Это очень просто для запроса для глубоких вложенных отношений (пользователь -> Друзья -> Друзья …) или используйте полевые псевдонимы, чтобы попросить одинаковое поле много раз. Атаки истощений ресурсов не являются специфическими для Graphql, но при работе с GraphQL мы должны быть очень осторожны с ними.
Есть некоторые смягчения, которые мы можем сделать здесь. Мы можем выполнять анализ затрат на запрос заранее и обеспечить некоторые ограничения на сумму данных, которые можно потреблять. Мы также можем реализовать тайм-аут, чтобы убить запросы, которые занимают слишком много времени, чтобы разрешить. Кроме того, поскольку GraphQL является просто разрешенным слоем, мы можем обрабатывать правоприменение пределов скорости на более низком уровне под GraphQL.
Если конечная точка API Graphql API мы пытаемся защитить, не публично, и предназначено для внутреннего потребления наших собственных клиентов (Web или Mobile), мы можем использовать подход белого и предварительно утверждения, которые сервер может выполнить. Клиенты могут просто попросить серверы выполнять предварительно утвержденные запросы с помощью уникального идентификатора запроса. Facebook, кажется, использует этот подход.
Аутентификация и авторизация – это другие проблемы, которые нам нужно подумать о работе с GraphQL. Мы обращаемся к ним до, после, или во время процесса разрешения GraphQL?
Чтобы ответить на этот вопрос, подумайте о GRAGHQL как DSL (конкретный язык домена) на вершине своей собственной логики получения данных Backend. Это просто один слой, который мы могли бы поставить между клиентами и нашей фактической службой данных (или нескольких услуг).
Подумайте о аутентификации и авторизации как другой слой. GraphQL не поможет с фактической реализацией аутентификации или логики авторизации. Это не предназначено для этого. Но если мы хотим поставить эти слои за GraphQL, мы можем использовать GraphQL для передачи токенов доступа между клиентами и исполнительной логикой. Это очень похоже на то, как мы делаем аутентификацию и авторизацию с помощью RESTSIL API.
Еще одна задача, которую GraphQL делает немного более сложным, это кэширование данных клиента. RESTFLY API легче кэшировать из-за своего словаря. Это место дает данные. Мы можем использовать сам местоположение в качестве ключа кэша.
С GraphQL мы можем принять аналогичный базовый подход и использовать текст запроса в качестве ключа для кэширования его ответа. Но этот подход ограничен, не очень эффективный, и может вызвать проблемы с согласованностью данных. Результаты нескольких запросов GraphQL могут легко перекрываться, и этот базовый кэширующий подход не будет учитывать перекрытие.
Есть блестящее решение этой проблемы, хотя. Подтверждение графика означает График кэш Отказ Если мы нормализуем ответ запроса GraphQL в плоский набор записей, предоставляя каждую запись в глобальном уникальном идентификаторе, мы можем кэшировать эти записи вместо того, чтобы кэшировать полные ответы.
Это не простой процесс, хотя. Будут записи, ссылающиеся с другими записями, и мы будем управлять там циклическим графом. Население и чтение кэша понадобится прохождение запроса. Нам нужно кодировать слой для обработки логики кэша. Но этот метод будет в целом будет намного более эффективным, чем кэширование на основе ответа. Relay.js это одна структура, которая принимает эту стратегию кэширования и автоматически управляет ее внутренне.
Возможно, самая важная проблема, которую мы должны беспокоиться с GraphQL, – это проблема, которая обычно называется N + 1 SQL-запросами. Поля на запрос GraphQL предназначены для автономных функций и разрешение этих полей с данными из базы данных могут привести к новой записи базы данных на разрешенное поле.
Для простой редкой логики конечной точки API легко проанализировать, обнаруживать и решать проблемы N + 1 путем улучшения построенных запросов SQL. Для GraphQL динамически разрешенных полей, это не так просто. К счастью, Facebook Pioneering одно возможное решение этой проблемы: DataLoader Отказ
Как подразумевает имя, DataLoader – это утилита, которую можно использовать для чтения данных из баз данных и сделать его доступным для функций Resolver GraphQl. Мы можем использовать DataLoader вместо того, чтобы прочитать данные непосредственно из баз данных с SQL-запросами, и DataLoader будет действовать как наш агент для уменьшения фактических запросов SQL, мы отправляем в базу данных.
DataLoader использует комбинацию дозирования и кэширования для достижения этого. Если один и тот же клиентский запрос привел к необходимости задавать базу данных о нескольких вещах, DataLoader можно использовать для консолирования этих вопросов и пакетно-нагрузки их ответов из базы данных. DataLoader также будет кэшировать ответы и сделать их доступными для последующих вопросов о тех же ресурсах.
Спасибо за прочтение.
Изучение реагировать или узел? Оформить заказ моих книг: