Apollo-link-rest: RESTサーバーリクエストをキューに入れるエレガントな方法は? 最大同時実行性、時間距離、スロットル🚙⟷🚕⟷🚗?

作成日 2019年01月20日  ·  7コメント  ·  ソース: apollographql/apollo-link-rest

私はapollo-link-restを使用して、無料のサードパーティのRESTAPIへの呼び出しを作成しています。 それは素晴らしいユースケースだと思います。

ただし、ご存知のとおり、サードパーティのAPIは、リクエストの同時実行性と、連続するAPIリクエスト間の最小の安全性のギャップに関して_respectで処理する必要があります_。 つまり、 100ミリ秒ごとよりも頻繁にサーバーにアクセスしていないことを確認します

apolloが通話を引き継いでいるので、時間をかけて通話ました。 偶然にも、完全なリクエストを解決するために追加のリクエストを起動するクエリを作成するのにそれほど時間はかかりません。 たとえば、 @exportディレクティブを使用します。

_一度に2回の通話_🚀🚀

const QUERY = gql`
  query RestData($email: String!) {
    # 1) Query for user 🚀
    users @rest(path: '/users/email?{args.email}', method: 'GET', type: 'User') {
      id @export(as: "id")
      firstName
      lastName
      # 2) Sub query for friends fires immediately as well 🚀
      friends @rest(path: '/friends/{exportVariables.id}', type: '[User]') {
        firstName
        lastName
      }
    }
  }
`;

n + 1クエリの問題の軽いケース

_私が今していること:フェッチのラッピング_

const restProviders = new RestLink({
  endpoints: {
    mySlowEndpoint: baseUrl
  },
  customFetch: (...args) =>
    new Promise((resolve, reject) => {
      // 🚙⟷🚕⟷🚗 Implementing my queue logic to fire of fetches
        resolve(fetch(...args));
      // when enough time has elapsed. 🚙⟷🚕⟷🚗 
    })
})

現在、フェッチプロセスをカスタムキューロジックでラップしていますが、これを統合できる「よりエレガントな方法」はありますか? 確かに、多くの人は、必ずしもすぐにクエリに失敗することなく、発信負荷をある程度制御したいと考えています。

最も参考になるコメント

多分私はグーグルからやって来る他の人々のために私が今していることを追加する必要があります。 現在、私はp-throttleレポ)を使用しています。

// (...)
import pThrottle from "p-throttle";

const restProviders = new RestLink({
  endpoints: {
    mySlowEndpoint: baseUrl
  },
  // Throttle fetches to max 1 concurrent request 🚀 and
  //  min. delay of 0.5 seconds 🚙⟷🚕⟷🚗 .
  customFetch: pThrottle( (...args) => {
    return fetch(...args);
  }, 1, 500)
})

// (...)

全てのコメント7件

多分私はグーグルからやって来る他の人々のために私が今していることを追加する必要があります。 現在、私はp-throttleレポ)を使用しています。

// (...)
import pThrottle from "p-throttle";

const restProviders = new RestLink({
  endpoints: {
    mySlowEndpoint: baseUrl
  },
  // Throttle fetches to max 1 concurrent request 🚀 and
  //  min. delay of 0.5 seconds 🚙⟷🚕⟷🚗 .
  customFetch: pThrottle( (...args) => {
    return fetch(...args);
  }, 1, 500)
})

// (...)

@ D1no customFetchを提案するつもりでしたが、あなたはすでにそれを行っています!

これが実際にApollo-link-restの直接構成可能な機能であるかどうかはわかりませんが、ドキュメントにこのようなスニペットを含めることはサポートします。

customFetchで何ができるかの例として、この情報をPRするためのドキュメント内の良い場所を教えていただけますか? 私はあなたが正しいと思います。 そのような構成可能性をapollo-link-restにスローすると、フェッチ方法論が結合されますが、これはあまりエレガントではありません。

PRでは、初心者が読んでいるためのより工夫された例として、p-queueを開始します。 GraphQLへのゲートウェイドラッグとしてapollo-link-restを真剣に使用している人は、ある時点で_並行性/デバウンスの管理_が必要になります。

ねえ@ D1noここでドキュメントを見つけることができます。 Complete options上にあるOptions見出しに配置することをお勧めします。

@tombartonに感謝します。 この問題をもう一度詳しく見てみると、とにかくフェッチ呼び出し用の単純なスロットルオプションを用意できるようにすることをお勧めします。

もともとカップリングフェッチと言っていましたが、実際はそうではありません。 ここで横行している(任意の)フェッチ方法論への呼び出し。 apollo-link-restを盲目的に/熱心に実行できるようにするために、上記のような単純な同時実行性とms制限オプションは、最終的にはそれほど悪い考えではないかもしれません。

const restProviders = new RestLink({
  endpoints: {
    mySlowEndpoint: baseUrl
  },
  maxConcurrency: 2 // Max Concurrency 🚀🚀
  minThrottle: 500 // Handling Rate Limit in ms 🚙⟷🚕⟷🚗 
})

および/またはクエリで指定できる

const QUERY = gql`
  query RestData($email: String!) {
    users @rest(path: '/users/email?{args.email}', method: 'GET', type: 'User') {
      id @export(as: "id")
      firstName
      lastName
      # NEW:       ⤥ 🚙⟷🚕     ⤥ 🚀🚀
      friends @rest(throttle: 500, concurrency: 2, path: '/friends/{exportVariables.id}', type: '[User]') {
        firstName
        lastName
      }
    }
  }
`;

結局のところ、フェッチ方法論が呼び出される頻度を管理する必要があるのはなぜですか(2階で何が起こっているかを気にする必要はありません)。 それについて少し考えます。 とにかく、 customFetchは、空白の要求だけでなく、現在のクエリに関する情報が渡される必要があります(人々が本当に必要な場合に賢明な決定を下せるようにするため)。

たぶん、メンテナ/スタッフの1人(@fbartho)がチップインできますか? メリットが認められれば、PRに時間を割いていただければ幸いです。

@ D1no私は正直にドキュメントに含めるというあなたの提案が好きでした。 -キューイングは、会社のアプリでやりたかった方法の反対です。 (たとえば、重複排除は私が作成したものです)。

これとは別に、エンドポイントは完全に異なる可能性があるため、「maxConcurrency / minThrottle」をグローバルな懸念事項として設定することを躊躇します。

ApolloLinkRestは、「Apolloにデータをプラグインする」ことを目的としています。これまで説明してきたこれらの懸念は、ネットワーク層、別名カスタムフェッチにあるべきだと実感しています。 -さらに、クエリパスごとにこれらの値をカスタマイズする可能性は低いと思います。そのため、GraphQLに設定を埋め込むのは煩わしいようです。

了解しました—最初にドキュメントへの追加をPRします。 その上にレイヤーをクリーム状にする前に、まずcustomFetchをボトムアウトする必要があります。

このページは役に立ちましたか?
0 / 5 - 0 評価