はじめに
Workatoは、SaaSとの連携を実現する製品ゆえに、SaaS製品のレートリミットとは切っても切れない関係にあります。そこで、今回はレートリミット対応について少し考えてみたいと思います。
エラーハンドリングだけではレートリミット対応は不十分
Workatoにはエラーハンドリングの仕組みが存在し、エラー発生時のリトライ回数(最大3回)とその待ち時間(最大10秒)を指定することが可能です。
しかし、待ち時間が最大10秒であることと、一定間隔のリトライしか対応していないため、エラーハンドリングだけではレートリミット対応は不十分であり、エラーハンドリングをレートリミットに活用する際には、実装に工夫が必要です。
レスポンスヘッダに記載されるレートリミットを確認して対応する
アプリケーションによっては、 RFC7231 などを参考にレスポンスヘッダにレートリミット関連の情報を出力しているものがあります。
Oktaを例にしますと、Oktaではレートリミットの上限と、レートリミットまでのリクエスト残数、レートリミットが解除される時刻(UNIX時)がAPIのレスポンスヘッダとして返されます。
https://developer.okta.com/docs/reference/rl-best-practices/ より
HTTP/1.1 200 OK
X-Rate-Limit-Limit: 1200
X-Rate-Limit-Remaining: 1199
X-Rate-Limit-Reset: 1609459200
以上をもとにレートリミット対応すると、次のようなレシピになります。
レスポンスヘッダは、Custom Actionを利用することで取得が可能です。
もちろん、このレシピの実装だけではレートリミット対応は不十分ですが(例えばレートリミットの情報を取得しているAPI自身がエラーとなった場合の処理や、バーストを考慮した処理など様々な考慮は必要となりますが、何をすべきかのヒントにはなるものと思います。
なお、他のSaaS製品においても、ヘッダの違いや出力される情報量の違いはありますが、同様の方法でレートリミットのハンドリングが可能です。ただし、Oktaとは異なりレートリミットの残数の出力がされないものも存在しますので、その場合はレシピに工夫は必要となります。
例えば、Slack Web APIの場合は Retry-After
というレスポンスヘッダからレートリミット解除までの待ち時間を確認することはできますが、レートリミットまでのリクエスト残数を確認することはできません。このため、レートリミットが発生したレスポンスをキャッチして、適切な処理の実装が必要となります。
指数バックオフ(Exponential Backoff)による対応
DeepLを例にしますと、DeepLではOktaのようなレートリミットに関する情報はレスポンスヘッダ等に出力されません。DeepLの場合は、レートリミットを含めたエラーハンドリングとして指数バックオフの実装を求めています。
When retrying failed requests, your application should implement an exponential-backoff strategy: increasing the delay time with each further failed request.
Workatoで指数バックオフを実装した場合、次のような感じになります。
なお、こちらも対応としては不十分な場合がありますので、あくまでもヒントとして参考としていただき、実際のレシピにおいては綿密な設計と実装のうえ運用いただければと思います。