🍀

【Shopify.dev和訳】API usage/Rate limits

2021/09/09に公開

この記事について

この記事は、API usage/Rate limitsの記事を和訳したものです。

記事内で使用する画像は、公式ドキュメント内の画像を引用して使用させていただいております。

Shopify アプリのご紹介

Shopify アプリである、「商品ページ発売予告アプリ | リテリア Coming Soon」は、商品ページを買えない状態のまま、発売日時の予告をすることができるアプリです。Shopify で Coming Soon 機能を実現することができます。

https://apps.shopify.com/shopify-application-314?locale=ja&from=daniel

Shopify アプリである、「らくらく日本語フォント設定|リテリア Font Picker」は、ノーコードで日本語フォントを使用できるアプリです。日本語フォントを導入することでブランドを演出することができます。

https://apps.shopify.com/font-picker-1?locale=ja&from=daniel

Shopify API レート制限

プラットフォームがすべての人にとって安定して公平であるようにするために、すべての ShopifyAPI はレート制限されています。 レート制限を適用するために、さまざまな戦略を使用しています。 開発者には、呼び出しを制限し、結果をキャッシュし、責任を持ってリクエストを再試行するための業界標準の手法を使用するようお願いしています。

API によるレート制限の比較

Shopify API は、いくつかの異なるレート制限方法を使用します。 これらについては以下で詳しく説明しますが、簡単に説明すると次のようになります。

API Rate-limiting method Standerd limit Shopify Plus limit
Admin API(GraphQL) 計算されたクエリコスト 50 points/second 100 points/second
Admin API(REST) リクエストベースの制限 2 requests/second 4 requests/second
Storefront API 時間ベースの制限 リクエストごとに最低 0.5 秒、ユーザー IP ごとに 60 秒 リクエストごとに最低 0.5 秒、ユーザー IP ごとに 120 秒
Payments Apps API (GraphQL) 計算されたクエリコスト 910 points/second 1820 points/second

リーキーバケットアルゴリズム

すべての ShopifyAPI は、リーキーバケットアルゴリズムを使用してリクエストを管理します。 このアルゴリズムを使用すると、アプリは時間の経過とともにまれなバーストで無制限の量のリクエストを行うことができます。
リーキーバケットのメタファーについて理解するための主なポイントは次のとおりです。
 - 各アプリはバケットにアクセスできます。 たとえば、60 個の「ビー玉」を保持できます。
 - 毎秒、ビー玉がバケットから取り出されます(ある場合)。 そうすれば、常により多くの余地があります。
 - 各 API リクエストでは、バケットにビー玉を投げる必要があります。
 - バケットがいっぱいになると、エラーが発生し、バケットで空きができるまで待つ必要があります。
このモデルにより、API 呼び出しを責任を持って管理するアプリは、必要に応じてリクエストをバーストするためのスペースを常にバケットに確保できます。 たとえば、1 秒あたり平均 20 リクエスト(「ビー玉」)であるのに、突然 30 リクエストを一度に行う必要がある場合でも、レート制限に達することなくそれを行うことができます。

リーキーバケットアルゴリズムの基本原則は、それらを適用するために使用される特定の方法に関係なく、すべてのレート制限に適用されます。

レート制限方法

Shopify は、レート制限を管理するために 3 つの異なる方法を使用します。 API が異なれば、ユースケースに応じて使用するメソッドも異なるため、アプリで発生するさまざまな種類のレート制限を理解してください。

リクエストベースの制限

アプリは 1 分あたり最大数のリクエストを行うことができます。 例:60 秒以内に 40 の API リクエスト。 返されるデータの量に関係なく、各リクエストは等しくカウントされます。

このメソッドは、REST 管理 API によって使用されます。

時間ベースの制限

アプリは、1 分あたり最大の時間を要するリクエストを行うことができます。 例:60 秒以内に 120 のリクエストがあり、各リクエストが返されるまでに 0.5 秒かかります。 より複雑なリクエストは時間がかかるため、それに比例して制限の大きな部分を占めます。

このメソッドは、StorefrontAPI によって使用されます。

計算されたクエリコスト

アプリは、1 分あたり最大ポイント数のリクエストを行うことができます。 例:60 秒以内に 1000 ポイント。 より複雑なリクエストはより多くのポイントを消費するため、それに比例して制限の大きな部分を占めます。

このメソッドは GraphQLAPI によって使用されます。

GraphQL Admin API のレート制限

GraphQL Admin API の呼び出しは、計算されたクエリコストに基づいて制限されます。つまり、リクエストの数ではなく、時間の経過に伴うリクエストのコストを考慮する必要があります。

GraphQL Admin API のレート制限は、アプリとストアの組み合わせに基づいています。これは、同じストアであっても、あるアプリからの呼び出しが別のアプリのレート制限に影響を与えないことを意味します。同様に、あるストアへの呼び出しは、同じアプリからであっても、別のストアのレート制限に影響を与えません。

アプリとストアの各組み合わせには、1000 コストポイントのバケットが与えられ、リーク率は 1 秒あたり 50 コストポイントです。つまり、クエリの合計コストは常に 1,000 ポイントを超えることはできず、その部屋は 1 秒あたり 50 ポイントの割合でアプリのバケットに作成されます。よりシンプルで低コストのクエリを作成することで、時間の経過とともにより多くのクエリを作成できます。

制限では、要求されたクエリコストと実際のクエリコストの組み合わせが使用されます。実行を開始する前に、アプリのバケットには、クエリの要求されたコストに対して十分なスペースが必要です。実行が完了すると、要求されたコストとクエリの実際のコストの差額がバケットに払い戻されます。

計算コスト

スキーマのすべてのフィールドには、整数のコスト値が割り当てられています。 クエリのコストは、各フィールドのコストの合計です。 クエリの実行は、クエリの実際のコストを知るための最良の方法です。

デフォルトでは、フィールドのコストは、フィールドが返すものに基づいています。

Field returns Cost value
Scalar 0
Enum 0
Object 1
Interface 1
Union 1
これらのデフォルトのコストは設定されていますが、Shopify はフィールドに手動のコストを設定する権利も留保します。

要求された実際のコスト

Shopify は、クエリ実行の前後の両方でクエリのコストを計算します。 要求されたコストは、要求されたフィールドの数に基づいています。 オブジェクトタイプフィールドが null を返すためにクエリが早期に終了したり、接続フィールドが要求されたよりも少ないエッジを返す可能性があるため、実際のコストは返された結果に基づいています。

単一クエリの制限

API への単一のクエリは 1,000 のコストを超えることはできません。 この制限は、クエリの要求されたコストに基づいてクエリが実行される前に適用されます。

入力配列の最大サイズ制限

配列を受け入れる入力引数の最大サイズは 250 です。入力配列が 250 項目を超えると、クエリとミューテーションはエラーを返します。

GraphQL のレスポンス

応答には、要求のコストとスロットルの状態に関する情報が含まれます。 このデータは、extensions key の下に返されます。

"extensions": {
    "cost": {
      "requestedQueryCost": 101,
      "actualQueryCost": 46,
      "throttleStatus": {
        "maximumAvailable": 1000,
        "currentlyAvailable": 954,
        "restoreRate": 50
      }
    }
  }

各フィールドが要求されたコストにどのように寄与するかについての詳細な内訳を取得するには、ヘッダー'X-GraphQL-Cost-Include-Fields':trueを要求に含めることができます。

"extensions": {
    "cost": {
      "requestedQueryCost": 101,
      "actualQueryCost": 46,
      "throttleStatus": ...,
      "fields": [
        {
          "path": [
            "shop"
          ],
          "definedCost": 1,
          "requestedTotalCost": 101,
          "requestedChildrenCost": 100
        },
        ...
      ]
    }
  }

一括操作

大量のデータをクエリしてフェッチするには、単一のクエリではなく一括操作を使用する必要があります。 一括操作は大量のデータを処理するように設計されており、単一のクエリにあるような最大コスト制限やレート制限はありません。

REST Admin API のレート制限

REST Admin API の呼び出しは、リクエストベースの制限によって管理されます。つまり、アプリが行う API 呼び出しの総数を考慮する必要があります。 さらに、リソースベースのレート制限とスロットルがあります。

REST Admin API のレート制限は、アプリとストアの組み合わせに基づいています。 これは、同じストアであっても、あるアプリからの呼び出しが別のアプリのレート制限に影響を与えないことを意味します。 同様に、あるストアへの呼び出しは、同じアプリからであっても、別のストアのレート制限に影響を与えません。

制限は、漏出バケットアルゴリズムを使用して計算されます。 レート制限を超えた後に行われたすべてのリクエストは抑制され、HTTP 429 Too ManyRequestsエラーが返されます。 十分な数のリクエストがバケットから空になった後、リクエストは再び成功します。 レート制限ヘッダーを使用すると、ストアのスロットルの現在の状態を確認できます。

バケットサイズとリークレートのプロパティによって、API のバースト動作とリクエストレートが決まります。

デフォルト設定は次のとおりです。

  • Bucket size: 40 requests/app/store
  • Leak rate: 2/second

バケットサイズを超えると、HTTP 429 Too ManyRequestsエラーが返されます。 バケットは、1 秒あたり 2 リクエストのリークレートで空になります。 スロットルを回避するために、1 秒あたり平均 2 つのリクエストを実行するようにアプリを構築できます。 スロットルは合格または不合格の操作です。 バケットに使用可能な容量がある場合、要求はキューイングまたは処理の遅延なしに実行されます。 それ以外の場合、要求は抑制されます。

GET リクエストには追加のレート制限があります。 pageパラメータの値が、要求されたリソースの 100,000 を超えるオフセットになると、429 Too ManyRequestsエラーが返されます。 たとえば、GET /admin/collects.json?limit=250&page=401へのリクエストは、100,250(250 x 401 = 100,250)のオフセットを生成し、429 応答を返します。

ヘッダーのレート制限

API リクエストに応答して送信された ShopifyX-Shopify-Shop-Api-Call-Limitヘッダーを使用して、すでに行ったリクエストの数を確認できます。 このヘッダーには、特定のストアに対して行ったリクエストの数が一覧表示されます。 例えば:

X-Shopify-Shop-Api-Call-Limit: 32/40

この例では、32が現在のリクエスト数で、40がバケットサイズです。 リクエスト数は、時間の経過とともにリーク率に応じて減少します。 たとえば、ヘッダーに39/40リクエストが表示されている場合、10 秒の待機期間の後、ヘッダーには19/40リクエストが表示されます。

Retry-After ヘッダー

リクエストがレート制限を超えると、429 Too ManyRequestsエラーとRetry-Afterヘッダーが返されます。 Retry-Afterヘッダーには、再度リクエストできるようになるまで待機する秒数が含まれています。 待機時間が経過する前に行われた要求はすべて抑制されます。

X-Shopify-Shop-Api-Call-Limit: 40/40
  Retry-After: 2.0

ストアフロント API のレート制限

Storefront API の呼び出しは、時間ベースの制限によって管理されます。つまり、リクエストの数ではなく、リクエストが完了するまでにかかる時間を考慮する必要があります。

バケットサイズとリークレートのプロパティによって、API のバースト動作とリクエストレートが決まります。 60 秒の制限は、アプリがインストールされているストアの ID ではなく、アプリを操作する購入者の IP アドレスに適用されます。 これは、販売者のストアでの購入者のトラフィックの増加によってアプリが抑制されないことを意味します。

デフォルト設定は次のとおりです。

  • Bucket size: 60 seconds/app/IP address
  • Leak rate: 1/second

Storefront API へのすべてのリクエストの実行には、最低 0.5 秒かかります。 リクエストが完了すると、合計経過時間が計算され、バケットから差し引かれます。

バケット制限の例

ユーザーがアプリを読み込んだときに、クライアントが複数の並列 API リクエストを行うとします。

  • それぞれ 0.5 秒以下かかる 20 の簡単なクエリ
  • それぞれ 1 秒かかる 15 のより複雑なクエリ
  • それぞれ 2 秒かかる 10 個の非常に複雑なクエリ
    総コストは次のようになります:(20⨉0.5)+(15⨉1.0)+(10⨉2.0)= 45 秒。

このシナリオでは、15 秒分のクエリを引き続き使用できます。

チェックアウトレベルのスロットル

Shopify は、StorefrontAPI で 1 分あたりに作成できるチェックアウトの量を制限します。 API クライアントがこのスロットルを超えると、200 Throttledエラー応答が返されます。 Shopify は、このシナリオに対応できるようにアプリを設計することをお勧めします。 たとえば、指数バックオフアルゴリズムを使用してリクエストキューを実装できます。

入力配列の最大サイズ制限

配列を受け入れる入力引数の最大サイズは 250 です。入力配列が 250 項目を超えると、クエリとミューテーションはエラーを返します。

リソースベースのレート制限

次の管理 API リソースには、GraphQL バージョンと REST バージョンの両方で、ストアに 50,000 の製品バリアントがある場合に有効になる追加のスロットルがあります。 このしきい値に達すると、1 日あたり 1,000 を超える新しいバリアントを作成できなくなります。

場合によっては、Shopify はプラットフォームの乱用を防ぐためにレート制限を実施する必要があります。 したがって、アプリは、ここにリストされているエンドポイントだけでなく、すべてのエンドポイントでレート制限を処理できるように準備する必要があります。

GraphQL のミューテーション

REST エンドポイント

アプリが特定のリソースの API レート制限に達すると、429 Too Many Requests 応答と、スロットルが適用されたというメッセージを受け取ります。

レート制限エラーの回避

ベストプラクティスを念頭に置いてアプリを設計することは、スロットルエラーを回避するための最良の方法です。 たとえば、列内の API リクエストをずらして、次の列に入れられた仕事が実行されるのを待っている間に他の処理タスクを実行できます。 アプリを設計するときは、次のベストプラクティスを考慮してください。

  • アプリに必要なデータのみを取得するようにコードを最適化します。
  • アプリが頻繁に使用するデータにはキャッシュを使用します。
  • よりスムーズな配布を求めるリクエストの割合を調整します。
  • エラーをキャッチするコードを含めます。 これらのエラーを無視してリクエストを続けようとすると、アプリは正常に回復できなくなります。
  • すべての API 応答に含まれる、アプリの API 使用状況に関するメタデータを使用して、アプリの動作を動的に管理します。
  • 再試行するのに十分な時間が経過するまで、コードは追加の API リクエストの作成を停止する必要があります。 推奨されるバックオフ時間は 1 秒です。

Shopify アプリのご紹介

Shopify アプリである、「商品ページ発売予告アプリ | リテリア Coming Soon」は、商品ページを買えない状態のまま、発売日時の予告をすることができるアプリです。Shopify で Coming Soon 機能を実現することができます。

https://apps.shopify.com/shopify-application-314?locale=ja&from=daniel

Shopify アプリである、「らくらく日本語フォント設定|リテリア Font Picker」は、ノーコードで日本語フォントを使用できるアプリです。日本語フォントを導入することでブランドを演出することができます。

https://apps.shopify.com/font-picker-1?locale=ja&from=daniel

Discussion

ログインするとコメントできます