GraphQL и микросервисная архитектура


176

Я пытаюсь понять, где GraphQL наиболее подходит для использования в архитектуре Microservice.

Есть некоторые споры о том, чтобы иметь только одну схему GraphQL, которая работает как API-шлюз, передавая запрос целевым микросервисам и вызывая их ответ. Микросервисы по-прежнему будут использовать протокол REST / Thrift для обмена информацией.

Другой подход - вместо этого иметь несколько схем GraphQL по одной на микросервис. Наличие меньшего сервера API Gateway, который направляет запрос в целевой микросервис со всей информацией о запросе + запросом GraphQL.

1-й подход

Наличие 1 схемы GraphQL в качестве шлюза API будет иметь обратную сторону: каждый раз, когда вы меняете ввод / вывод контракта на микросервис, мы должны соответствующим образом изменять схему GraphQL на стороне шлюза API.

2-й подход

Если для нескольких микросервисов используется несколько схем GraphQL, имейте в виду, что в GraphQL реализовано определение схемы, а потребителю необходимо учитывать ввод / вывод данных, предоставляемый микросервисом.

Вопросы

  • Считаете ли вы GraphQL подходящим для проектирования микросервисной архитектуры?

  • Как бы вы разработали API-шлюз с возможной реализацией GraphQL?

Ответы:


242

Определенно подход № 1.

То, что ваши клиенты общаются с несколькими службами GraphQL (как в подходе № 2), полностью сводит на нет цель использования GraphQL в первую очередь, то есть предоставления схемы по всем данным вашего приложения, чтобы можно было получать ее за один прием.

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

GraphQL и микросервисы идеально подходят, потому что GraphQL скрывает тот факт, что у вас есть микросервисная архитектура от клиентов. С внутренней стороны вы хотите разделить все на микросервисы, но с точки зрения внешнего интерфейса вы бы хотели, чтобы все ваши данные поступали из единого API. Использование GraphQL - лучший из известных мне способов, который позволяет вам делать и то, и другое. Он позволяет вам разделить ваш бэкэнд на микросервисы, в то же время предоставляя единый API для всего вашего приложения и позволяя объединять данные из разных сервисов.

Если вы не хотите использовать REST для своих микросервисов, вы, конечно, можете иметь каждый из них с собственным API-интерфейсом GraphQL, но у вас все же должен быть шлюз API. Причина, по которой люди используют шлюзы API, состоит в том, чтобы сделать их более управляемыми для вызова микросервисов из клиентских приложений, а не потому, что они хорошо вписываются в шаблон микросервисов.


2
@helfer: Это действительно имеет смысл :) спасибо. У меня есть несколько вопросов поверх этого великолепного ответа. - Вы говорите, что GraphQL должен использоваться в качестве шлюза API? - Допустим, у меня есть микросервис заказа, который предоставляет конечную точку REST или GraphQL. Как только я закончу с этим, мне придется обновить основную схему GraphQL, чтобы она отражала те же данные, что и микросервис? Разве это не звучит как дублирование или отход от культуры микросервиса, которая должна быть развернута независимо? Любые изменения в микросервисе должны быть отражены / продублированы в основной схеме GraphQL?
Фабрицио Фенольо

13
@Fabrizio - хорошая вещь с GraphQL в том, что даже если бэкэнд REST API изменяется, схема GraphQL может оставаться прежней, если есть способ получить данные, которые ранее предоставлялись сервисом REST. Если он предоставляет больше данных, то канонический способ справиться с этим - просто добавить новые поля / типы в существующую схему. Люди из Facebook, создавшие GraphQL, сказали мне, что никогда не вносили принципиальных изменений в свою схему за четыре года. Все внесенные изменения были аддитивными, что означает, что новые клиенты могут использовать новые функции, в то время как старые клиенты будут продолжать работать.
помощник

4
Правильно! :) Спасибо, что написали это! Я следую за тобой на Medium и на github через репо Apollo! Ваши статьи и посты очень ценны! :) Продолжайте хорошую работу! Я также думаю, что среднюю статью с темой GraphQL + Microservices будет очень приятно читать!
Фабрицио Фенольо

1
Спасибо, я буду иметь это в виду. Определенно планирую написать о GraphQL и Microservices в какой-то момент, но, вероятно, не в ближайшие пару недель.
помощник

Как насчет комбинации варианта № 2 и github.com/AEB-labs/graphql-weaver ?
Мохсен

35

Смотрите статью здесь , где говорится, как и почему подход № 1 работает лучше. Также посмотрите на изображение ниже, взятое из статьи, которую я упомянул: введите описание изображения здесь

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

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

Следующая статья объясняет эти два преимущества вместе с другими очень хорошо: https://nordicapis.com/7-unique-benefits-of-using-graphql-in-microservices/


Привет, извините за вопросы noob, но разве ваш шлюз graphQL не является новой точкой хранения? Например, если у меня есть служба корзины, которая внезапно перезапрошена, мой шлюз graphQL тоже не сломается? В принципе, я не уверен в его роли. Предполагается, что этот шлюз содержит много распознавателей для каждого сервиса?
Эрик Бурел

1
@EricBurel Спасибо за вопрос. На самом деле, насколько я понял из статьи, все схемы из разных сервисов объединены в одну схему GraphQL, поэтому, как вы упомянули, другие сервисы все еще находятся в своих собственных наборах данных. Что касается возможности единственного источника отказа для шлюза graphQL, всегда есть другие варианты, такие как предоставление плана резервного копирования. Пожалуйста, прочитайте эту статью ( labs.getninjas.com.br/… ) для получения дополнительной информации. Надеюсь это поможет.
Enayat

Как вы тестируете центральный шлюз API и отдельные сервисы? Вы делаете интеграцию или насмешливый ответ http?
Хайме Сангкап

7

Для подхода № 2, на самом деле, я выбираю именно это, потому что это намного проще, чем обслуживать надоедливый API-шлюз вручную. Таким образом, вы можете развивать свои услуги самостоятельно. Сделай жизнь намного проще: P

Есть несколько отличных инструментов для объединения схем в одну, например, graphql-weaver и apollo's graphql-tools , которые я использую graphql-weaver, они просты в использовании и отлично работают.


Использование GraphQL в Android обязательно, чтобы я создал файл .graphql со всеми запросами? Или я могу просто создать их в коде без этого файла?
МауроАлександро

1
@MauroAlexandro Я не андроид, но вы можете иметь запросы в разных файлах. Это больше проблема дизайна. ИМХО, я предпочитаю первый :)
HFX

5

По состоянию на середину 2019 года решение для 1-го подхода теперь носит название « Федерация схем », придуманное людьми Apollo (ранее это часто называли сшивкой GraphQL). Они также предлагают модули @apollo/federationи @apollo/gatewayдля этого.

ДОБАВИТЬ: Обратите внимание, что с федерацией схемы вы не можете изменять схему на уровне шлюза. Так что для каждого бита, который вам нужен в вашей схеме, вам нужен отдельный сервис.


Также справедливо знать, что это решение требует Apollo Server, который немного ограничен в бесплатной версии (максимум 25 миллионов запросов в месяц)
Маркс

0

Начиная с 2019 года, лучший способ - написать микросервисы, которые реализуют спецификацию шлюза apollo, а затем склеить эти сервисы, используя шлюз, следуя подходу № 1. Самый быстрый способ построить шлюз - это образ докера, подобный этому. Затем используйте docker-compose для одновременного запуска всех сервисов:

version: '3'

services:
    service1:
        build: service1
    service2:
        build: service2
    gateway:
        ports:
            - 80:80
        image: xmorse/apollo-federation-gateway
        environment: 
            - CACHE_MAX_AGE=5
            - "FORWARD_HEADERS=Authorization, X-Custom-Header" # default is Authorization, pass '' to reset
            - URL_0=http://service1
            - URL_1=http://service2

0

Как описано в этом вопросе, я считаю, что использование специального шлюза API в качестве службы оркестровки может иметь смысл для сложных корпоративных приложений. GraphQL может быть хорошим выбором технологии для этой службы оркестровки, по крайней мере, в части запросов. Преимущество вашего первого подхода (одна схема для всех микросервисов) заключается в возможности объединять данные из нескольких микросервисов в один запрос. Это может или не может быть очень важным в зависимости от вашей ситуации. Если графический интерфейс пользователя требует одновременного рендеринга данных из нескольких микросервисов, этот подход может упростить клиентский код, так что один вызов может вернуть данные, которые подходят для связывания данных с элементами графического интерфейса таких структур, как Angular или React. Это преимущество не распространяется на мутации.

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

В этом сравнении GraphQL с REST вы обнаружите, что GraphQL не так эффективен, как RESTful API, поэтому я бы не рекомендовал заменять REST на GraphQL для API данных.


0

На вопрос 1 Intuit признал мощь GraphQL несколько лет назад, когда он объявил о переходе на одну экосистему Intuit API ( https://www.slideshare.net/IntuitDeveloper/building-the-next-generation-of-quickbooks-app-integrations -quickbooks-connect-2017 ). Intuit решил пойти с подходом 1. Упомянутый вами недостаток на самом деле не позволяет разработчикам вносить критические изменения схемы, которые потенциально могут нарушить работу клиентских приложений.

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

  1. При разработке нового микросервиса для домена инженеры (серверная часть / интерфейс / заинтересованные стороны) согласовывают схему для объектов домена. После того как схема утверждена, она объединяется со схемой главного домена (универсальной) и развертывается на шлюзе. Передовые инженеры могут начать кодирование клиентских приложений с этой схемой, в то время как внутренние инженеры реализуют эту функциональность. Наличие одной универсальной схемы означает, что нет двух микросервисов с избыточной функциональностью.
  2. GraphQL помог клиентским приложениям стать проще и быстрее. Хотите получать данные из / обновлять данные для нескольких микросервисов? Все клиентские приложения должны запускать ОДИН запрос GraphQL, а уровень абстракции API Gateway позаботится о получении и сопоставлении данных из нескольких источников (микросервисов). Платформы с открытым исходным кодом, такие как Apollo ( https://www.apollographql.com/ ), ускорили темпы внедрения GraphQL.

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

На вопрос 2: Мы создали специальный уровень абстракции в шлюзе API, который знает, какая часть схемы принадлежит какому сервису (провайдеру). Когда поступает запрос, уровень абстракции направляет запрос в соответствующие службы. Как только базовый сервис возвращает ответ, уровень абстракции отвечает за возврат запрошенных полей.

Тем не менее, сегодня существует несколько платформ (сервер Apollo, graphql-yoga и т. Д.), Которые позволяют быстро создать уровень абстракции GraphQL.


0

Я работал с GraphQL и микросервисами

Исходя из моего опыта, мне подходит комбинация обоих подходов в зависимости от функциональности / использования, у меня никогда не будет единого шлюза, как в подходе 1 ... но я буду использовать graphql для каждого микросервиса как подход 2.

Например, основываясь на изображении ответа от Enayat, в этом случае я хотел бы иметь 3 шлюза графика (не 5, как на рисунке)

введите описание изображения здесь

  • Приложение (продукт, корзина, доставка, инвентарь, необходимые / связанные с другими услугами)

  • Оплата

  • пользователь

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

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

Этот способ легче ...

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

  • Когда шлюз созревает, растет, использование известно или у вас есть больше опыта в области, вы можете определить, какие части схемы могут иметь собственные шлюзы (... случилось со мной с огромной схемой, взаимодействующей с git-репозиториями Я отделил шлюз, который взаимодействует с репозиторием, и увидел, что единственной информацией, необходимой для ввода / связанной информации, был ... путь к папке и ожидаемая ветвь)

  • История ваших репозиториев более понятна, и у вас может быть репозиторий / разработчик / команда, предназначенная для шлюза и задействованных микросервисов.

ОБНОВИТЬ:

У меня есть кластер kubernetes онлайн, который использует тот же подход, который я описываю здесь со всеми бэкэндами с использованием GraphQL, все с открытым исходным кодом, вот основной репозиторий: https://github.com/vicjicaman/microservice-realm

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


-3

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


Даже при отсутствии «правильного определения», это хорошо понимаемая концепция, которая четко разграничена в контексте вопроса. Кроме того, ваш ответ не касается вопроса вообще.
Рой Принс

-7

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


2
Извините, но это вообще не относится к вопросу ОП. Речь идет о двух конкретных подходах с использованием GraphQL. Это, возможно, было бы лучше поместить в качестве комментария.
tiomno
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.