GraphQLとマイクロサービスアーキテクチャ


176

マイクロサービスアーキテクチャ内でGraphQLを使用するのに最適な場所を理解しようとしています。

APIゲートウェイとして機能する1つのGraphQLスキーマのみを使用して、リクエストされたマイクロサービスにリクエストをプロキシし、そのレスポンスを強制することについては、いくつかの議論があります。マイクロサービスは依然として通信の考え方にREST / Thriftプロトコルを使用します。

代わりに、マイクロサービスごとに1つずつ、複数のGraphQLスキーマを使用する方法もあります。リクエストのすべての情報とGraphQLクエリを使用して、リクエストをターゲットのマイクロサービスにルーティングする小さなAPIゲートウェイサーバーを用意します。

最初のアプローチ

1つのGraphQLスキーマをAPIゲートウェイとして使用すると、マイクロサービスコントラクトの入出力を変更するたびに、それに応じてAPIゲートウェイ側でGraphQLスキーマを変更する必要があるという欠点があります。

2番目のアプローチ

マイクロサービスごとに複数のGraphQLスキーマを使用する場合、GraphQLがスキーマ定義を適用し、コンシューマーはマイクロサービスから提供される入出力を尊重する必要があるため、ある意味で理にかなっています。

ご質問

  • GraphQLがマイクロサービスアーキテクチャの設計に適しているかどうか。

  • GraphQLを実装できるAPIゲートウェイをどのように設計しますか?

回答:


242

間違いなく#1にアプローチします。

クライアントが複数のGraphQLサービスと通信すること(アプローチ#2のように)は、最初にGraphQLを使用する目的を完全に無効にします。これは、アプリケーションデータ全体にスキーマを提供して、1回の往復でそれをフェッチできるようにすることです。

持つシェアード・ナッシング・アーキテクチャは、microservicesの観点から合理的なようですが、あなたはあなたのmicroservicesの1つを変更するたびに、あなたが更新する必要があるため、クライアント側のコードのためには、絶対的な悪夢である可能性があるすべてのあなたの顧客のを。あなたは間違いなくそれを後悔するでしょう。

GraphQLとマイクロサービスは完璧に適合します。これは、GraphQLがクライアントからマイクロサービスアーキテクチャを持っているという事実を隠すためです。バックエンドの観点からは、すべてをマイクロサービスに分割する必要がありますが、フロントエンドの観点からは、すべてのデータを単一のAPIから取得する必要があります。GraphQLを使用することは、私が知っている最良の方法であり、両方を実行できます。バックエンドをマイクロサービスに分割しながら、すべてのアプリケーションに単一のAPIを提供し、さまざまなサービスのデータ間での結合を可能にします。

マイクロサービスにRESTを使用したくない場合は、もちろん、それぞれに独自のGraphQL APIを持たせることができますが、それでもAPIゲートウェイが必要です。人々がAPIゲートウェイを使用する理由は、クライアントアプリケーションからマイクロサービスを呼び出すのをより管理しやすくするためであり、マイクロサービスパターンによく適合するためではありません。


2
@helfer:これは本当に理にかなっています:)ありがとう。このゴージャスな答えに加えて、いくつか質問があります。-GraphQLをAPIゲートウェイとして使用する必要があるとおっしゃっていますか。-RESTまたはGraphQLエンドポイントを公開する注文マイクロサービスがあるとします。終了したら、メインのGraphQLスキーマを更新して、マイクロサービスが公開するものとまったく同じデータを反映する必要がありますか?独立して展開する必要があるマイクロサービスカルチャから重複したり、離れたりしているように聞こえませんか?マイクロサービスへの変更は、メインのGraphQLスキーマに反映または複製する必要がありますか?
Fabrizio Fenoglio 2016年

13
@Qabrizio GraphQLの良いところは、RESTサービスが以前に公開したデータを取得する方法がある限り、バックエンドREST APIが変更されても、GraphQLスキーマは同じままであるということです。それがより多くのデータを公開する場合、これに対処する標準的な方法は、既存のスキーマに新しいフィールド/タイプを追加することです。GraphQLを作成したFacebookの人々は、4年間でスキーマに重大な変更を加えたことはないと語っています。彼らが行ったすべての変更は付加的なものでした。つまり、新しいクライアントが新しい機能を使用できる一方で、古いクライアントは引き続き機能します。
ヘルファー2016年

4
正しい!:)これを書いてくれてありがとう!Mediumとgithubでapolloリポジトリをフォローしています!あなたの記事と投稿は非常に貴重です!:)良い仕事を続けてください!また、GraphQL +マイクロサービスのトピックを含む中程度の記事は、非常に楽しいものになると思います。
Fabrizio Fenoglio 2016年

1
よろしくお願いします。間違いなくある時点でGraphQLとマイクロサービスについて書くことを計画していますが、おそらく今後数週間はそうではありません。
ヘルファー2016

オプション#2とgithub.com/AEB-labs/graphql-weaverの組み合わせはどう ですか?
Mohsen 2018

35

アプローチ#1がより効果的に機能する方法と理由については、こちらの記事をご覧ください。私が言及した記事から取られた以下の画像も見てください: ここに画像の説明を入力してください

すべてを単一のエンドポイントの背後に配置することの主な利点の1つは、各要求に独自のサービスがある場合よりもデータを効率的にルーティングできることです。これは、GraphQLでよく宣伝されている値であり、複雑さとサービスクリープが軽減されますが、結果として得られるデータ構造により、データの所有権を非常に明確に定義し、明確にすることができます。

GraphQLを採用することのもう1つの利点は、データの読み込みプロセスを大幅に制御できることを根本的に主張できることです。データローダーのプロセスは独自のエンドポイントに入るので、リクエストを部分的、完全、または注意して受け入れることができ、それによってデータの転送方法を非常に細かく制御できます。

次の記事では、これら2つの利点とその他の利点について詳しく説明しています。https//nordicapis.com/7-unique-benefits-of-using-graphql-in-microservices/


こんにちは、noobの質問は申し訳ありませんが、graphQLゲートウェイは新しい保持ポイントではありませんか?たとえば、突然過剰に要求されたバスケットサービスがある場合、graphQLゲートウェイも壊れませんか?基本的に私はその役割がわかりません、このゲートウェイには各サービスの多くのリゾルバーが含まれているはずですか?
Eric Burel、2018年

1
@EricBurel質問ありがとうございます。実際、記事から理解できる限り、さまざまなサービスのすべてのスキーマは1つのGraphQLスキーマに統合されているため、前述のように、他のサービスは引き続き独自のデータセットに存在します。graphQLゲートウェイの単一の障害発生の可能性に関しては、バックアップ計画の提供など、他のオプションが常にあります。詳細については、この記事(labs.getninjas.com.br/…)をお読みください。お役に立てれば。
Enayat 2018年

中央APIゲートウェイと個々のサービスをどのようにテストしますか?統合またはhttp応答のモックを行っていますか?
Jaime Sangcap

7

アプローチ#2の場合、実際には私が選択する方法です。迷惑なAPIゲートウェイを手動で保守するよりもはるかに簡単だからです。この方法で、独自にサービスを開発できます。人生をはるかに楽にする:P

一つにスキーマを結合するいくつかの素晴らしいツールがありますが、例えばgraphql・ウィーバーとアポロのgraphql-ツール、私が使用しているgraphql-weaver、それが使いやすいですし、素晴らしい作品。


AndroidでGraphQLを使用するには、すべてのクエリを含む.graphqlファイルを作成する必要がありますか?または、このファイルなしでコードでそれらを作成できますか?
MauroAlexandro

1
@MauroAlexandro私はアンドロイドの男ではありませんが、クエリを別のファイルに含めることができます。それはデザインの問題です。私見、私は最初のものを好む:)
HFX

5

2019年半ばの時点で、1番目のアプローチのソリューションは、「スキーマフェデレーションという名前がアポロの人々によって造られました(以前は、これはしばしばGraphQLスティッチングと呼ばれていました)。彼らはまた、このためのモジュール@apollo/federationを提案します@apollo/gateway

追加:スキーマフェデレーションでは、ゲートウェイレベルでスキーマを変更できないことに注意してください。したがって、スキーマに必要なすべてのビットについて、個別のサービスを用意する必要があります。


このソリューションには、無料バージョンでわずかに制限されているApolloサーバーが必要であることを知っていることも有効です(1か月あたり最大2500万クエリ)
Marx

0

2019年の時点で、最良の方法は、アポロゲートウェイ仕様を実装するマイクロサービスを記述し、アプローチ1に従ってゲートウェイを使用してこれらのサービスを接着することです。以下のようなゲートウェイを構築するための最速の方法は、ドッキングウィンドウの画像であるこの1つは その後、同時にすべてのサービスを開始するためにドッカ-コンを使用します。

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は、少なくともクエリに関しては、そのオーケストレーションサービスに適したテクノロジーの選択肢になる可能性があります。最初のアプローチ(すべてのマイクロサービスに対して1つのスキーマ)の利点は、複数のマイクロサービスからのデータを1つのリクエストでまとめることができることです。これは、状況によっては非常に重要な場合とそうでない場合があります。GUIが複数のマイクロサービスからのデータを一度にレンダリングすることを要求する場合、このアプローチはクライアントコードを簡素化し、単一の呼び出しがAngularやReactなどのフレームワークのGUI要素とのデータバインディングに適したデータを返すことができるようにします。この利点は突然変異には当てはまりません。

欠点は、データAPIとオーケストレーションサービスの間の密結合です。リリースをアトミックにすることはできなくなりました。データAPIに後方互換性のない変更を導入しない場合は、リリースをロールバックするときにのみ複雑さが生じる可能性があります。たとえば、オーケストレーションサービスに対応する変更を加えた2つのデータAPIの新しいバージョンをリリースしようとしていて、それらのリリースの1つをロールバックする必要があるが、もう1つはロールバックする必要がない場合、いずれにしても3つすべてをロールバックする必要があります。

このGraphQLとRESTの比較では、GraphQLはRESTful APIほど効率的ではないため、データAPIのRESTをGraphQLで置き換えることはお勧めしません。


0

質問1について、Intuitは、One Intuit APIエコシステム(https://www.slideshare.net/IntuitDeveloper/building-the-next-generation-of-quickbooks-app-integrations)への移行を発表した数年前にGraphQLの威力を認めました-quickbooks-connect-2017)。Intuitはアプローチ1を選択しました。あなたが言及した欠点は、クライアントアプリケーションを混乱させる可能性のある破壊的なスキーマ変更を開発者が実際に導入することを防ぎます。

GraphQLは、さまざまな方法で開発者の生産性の向上に貢献しています。

  1. ドメインの新しいマイクロサービスを設計するとき、エンジニア(バックエンド/フロントエンド/関係者)はドメインエンティティのスキーマに同意します。スキーマが承認されると、マスタードメインスキーマ(ユニバーサル)とマージされ、ゲートウェイに展開されます。フロントエンドエンジニアは、このスキーマを使用してクライアントアプリケーションのコーディングを開始し、バックエンドエンジニアは機能を実装できます。1つのユニバーサルスキーマがあるということは、冗長な機能を持つ2つのマイクロサービスがないことを意味します。
  2. GraphQLは、クライアントアプリケーションのシンプル化と高速化を支援しました。/ update dataから複数のマイクロサービスにデータを取得したいですか?クライアントアプリケーションが行う必要があるのは、1つのGraphQLリクエストを起動することだけです。APIGateway抽象化レイヤーは、複数のソース(マイクロサービス)からデータをフェッチして照合するように注意します。Apollo(https://www.apollographql.com/)のようなオープンソースフレームワークにより、GraphQLの採用が加速しています。

  3. 最新のアプリケーションではモバイルが最初の選択肢であるため、グラウンドゼロからより低いデータ帯域幅要件に対応できるように設計することが重要です。GraphQLは、クライアントアプリが特定のフィールドのみをリクエストできるようにすることで役立ちます。

質問2:スキーマのどの部分がどのサービス(プロバイダー)によって所有されているかを認識するカスタムアブストラクションレイヤーをAPI Gatewayに作成しました。クエリ要求が到着すると、抽象化層が要求を適切なサービスに転送します。基礎となるサービスが応答を返すと、抽象化レイヤーは要求されたフィールドを返す責任があります。

ただし、今日ではいくつかのプラットフォーム(Apolloサーバー、graphql-yogaなど)があり、それらを使用するとGraphQL抽象化レイヤーをすぐに構築できます。


0

GraphQLとマイクロサービスを使用しています

私の経験に基づくと、機能/使用方法に応じて両方のアプローチを組み合わせて機能しますが、アプローチ1のように単一のゲートウェイを使用することはありませんが、アプローチ2として各マイクロサービスのgraphqlをネザーにします。

たとえば、Enayatからの回答の画像に基づいて、私がこの場合に行うことは、3つのグラフゲートウェイを持つことです(画像のように5ではありません)。

ここに画像の説明を入力してください

  • アプリ(製品、バスケット、配送、在庫、他のサービスに必要/リンクされている)

  • 支払い

  • ユーザー

この方法では、認証トークン、ユーザーID、支払いID、支払いステータスなど、依存するサービスから公開される必要な/リンクされた最小限のデータの設計に特別な注意を払う必要があります

たとえば、私の経験では、「ユーザー」ゲートウェイがあります。そのGraphQLには、ユーザークエリ/ミューテーション、ログイン、サインイン、サインアウト、パスワードの変更、メールの回復、メールの確認、アカウントの削除、プロファイルの編集、写真のアップロードがあります。 、など...このグラフ自体は非常に大きい!、最後に他のサービス/ゲートウェイはユーザーID、名前、トークンなどの結果の情報のみを処理するため、分離されています。

この方法は簡単です...

  • 使用状況に応じて、さまざまなゲートウェイノードをスケーリングまたはシャットダウンします。(たとえば、人々は常に自分のプロフィールを編集したり、支払いを行ったりするわけではないかもしれませんが、製品の検索がより頻繁に使用される可能性があります)。

  • ゲートウェイが成熟し、成長し、使用法が判明するか、ドメインの専門知識が増えると、ゲートウェイを所有できるスキーマの一部であると特定できるようになります(gitリポジトリとやり取りする巨大なスキーマで発生しました... 、リポジトリとやり取りするゲートウェイを分離しましたが、必要な/リンクされた情報のみが...フォルダパスと予期されるブランチであることがわかりました)

  • リポジトリの履歴がより明確になり、ゲートウェイとそれに関連するマイクロサービス専用のリポジトリ/開発者/チームを持つことができます。

更新:

私がここで説明しているのと同じアプローチを使用しているkubernetesクラスターをオンラインで使用しています。すべてのバックエンドがGraphQLを使用し、すべてのオープンソースです。ここにメインリポジトリがあります。https//github.com/vicjicaman/microservice-realm

これは私の回答の更新です。回答/アプローチが実行中のコードをバックアップし、参照/確認できるようにした方が良いと思うので、これが役立つことを願っています。


-3

マイクロサービスアーキテクチャには適切な定義がないため、このスタイルに固有のモデルはありませんが、ほとんどのモデルには顕著な特徴がほとんどありません。マイクロサービスアーキテクチャの場合、各サービスは個々の小さなコンポーネントに分割できます。アプリケーションの整合性に影響を与えることなく、個別に調整および展開されます。つまり、カスタムマイクロサービスアプリの開発を通じてアプリケーションを再デプロイすることなく、いくつかのサービスを簡単に変更できます。


「適切な定義」が欠けていても、それはよく理解された概念であり、質問の文脈で明確に区別されます。それはさておき、あなたの答えはその質問にまったく取り組みません。
ロイプリンス

-7

マイクロサービスの詳細については、GraphQLがサーバーレスアーキテクチャでも完璧に機能すると思います。私はGraphQLを使用していませんが、同様のプロジェクトがあります。多くの関数を呼び出して単一の結果に集中させるアグリゲーターとして使用します。GraphQLにも同じパターンを適用できると思います。


2
申し訳ありませんが、これはOPの質問にはまったく関係ありません。問題は、GraphQLを使用する2つの特定のアプローチについてです。これはコメントとして入れたほうがいいかもしれません。
tiomno 2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.