NocoBaseワークフローで外部APIのレート制限を回避する

2024.06.03

こんにちは、柳澤です。

今回はNocoBaseワークフローのDelayノードを利用して、外部API利用時に発生しがちなレート制限を回避してみます。

※本記事ではNocobase 1.0 aplha-15の機能を利用しています。

困っていたこと

ワークフローで外部のAPIを叩く際、レート制限に引っかかってしまい正常に処理を完了できない。

例えば、Slack APIの場合、各メソッド毎にTierという区分でレート制限が設けられています。
レート制限に達した場合、解除されるまでAPIはエラーレスポンスを返すため処理を続行できなくなってしまいます。

今回はレート制限が発生したら待機し、待機後に処理を再開するワークフローを構築してみます。

なお、外部APIのレスポンスを扱う方法・ワークフローの構築方法はこちらの記事をご覧ください。

どう対応すればいいの?

HTTP requestを行い、そのレスポンスのHTTPステータスコードが429である場合にDelayノードで待機させ、待機後に再度HTTP requestを行うワークフローを構築します。

今回はCloudflare社が提供するCloudflare Rate Limiting Demonstration Pageを利用してレート制限を擬似的に発生させます。
Cloudflare Rate Limiting Demonstration Pageでは、1分間に10回を超えてリクエストするとHTTPステータスコード:429のレスポンスが返って来ます。

全体像としては下記のようになります。

非同期実行ワークフローを作成する

レート制限回避の要であるDelayノードは同期実行モード(Synchronously)では使用できません。
そのため、Execute mode: Asynchronouslyに設定したワークフローを作成します。

動作確認しやすくするため、トリガータイプをPost-Actionにします。

リトライループを定義する

ループノードを利用して、再試行が行われるようにします。
ここでは、Loop target10に設定しています。この数字はループの回数として扱われます。

HTTP requestノードの結果に応じて条件分岐させる

Loopノード内にHTTP requestノードを配置し、外部APIを叩きます。
リクエスト後の条件ノードで続行可否を判定するため、Ignore failed request and continue workflowにチェックを入れます。

後続ノードに条件ノードを配置し条件として「HTTP requestノード実行結果のHTTP status = 429」を設定します。
この条件ノードの後続ノードでは、上記条件が「はい」の場合にレート制限解除待機、「いいえ」の場合にはワークフローを終了させるよう分岐させます。

「はい」側にDelayノードを配置します。 Delayノードの設定では、Cloudflare Rate Limiting Demonstration Pageの仕様に合わせて1分のDurationを指定します。

次いで「いいえ」側にワークフローを終了させるよう各種ノードを配置します。
条件ノードを配置し、「HTTP requestノード実行結果のHTTP status = 200」で条件分岐をさせ、「はい」「いいえ」に応じて正常終了/異常終了のEnd processをそれぞれ配置します。

最後に、ループノードを抜けた先、終了ノードの前にもEnd processを配置します。
このノードに到達する条件は10回試行したがレート制限を回避できなかった場合ですので、異常終了として扱う必要があります。
(デフォルトの終了ノードだと正常終了扱いになってしまう)

ここまですべてのノードを配置したワークフローは下記の通りとなります。

動作確認

作成したワークフローをフォームのボタンに割り当て12回連打し、ワークフローの実行履歴を確認します。
ID: 56までの実行は既に解決済みとなっていますが、ID: 57以降はまだ処理中のままとなっており、レート制限解除待機中であることが伺えます。

1分ほど待って再度確認した所、ID: 57以降の実行も解決済みとなっており、正常にワークフローを終了できたことが確認できます。

まとめ

レート制限を回避するには、「ループノードで再帰」「条件ノードでレート制限を検知」「Delayノードで制限解除待機」の3点が要となります。
これらをうまく活用することで、様々なAPIのレート制限を回避できるかと思います。ご活用あれ~!