目的
APIを叩く回数に制限をかけないとユーザーに想定以上にAPIを叩かれてしまい、DBに大きな負荷がかかる可能性が実際の業務では起き得ると考え、スロットリングを実装してみることとした。
実施環境
ハードウェア環境
項目 | 情報 |
---|---|
OS | macOS Catalina(10.15.7) |
ハードウェア | MacBook Air (11-inch, Early 2015) |
プロセッサ | 1.6 GHz デュアルコアIntel Core i5 |
メモリ | 4 GB 1600 MHz DDR3 |
グラフィックス | intel HD Graphics 6000 1536 MB |
ソフトウェア環境
項目 | 情報 |
---|---|
homebrew | 3.3.8 |
mysql | Ver 8.0.27 for macos10.15 on x86_64 |
python | 3.8.12 |
anaconda | 4.10.1 |
django | 21.2.4 |
pip | 3.1.2 |
概要
setting.pyでスロットリングの情報をデフォルトのものに上書きをして、APIの呼び出し回数に制限をかけることができる。
自由度が高く、認証済みユーザー/非認証ユーザー別、ページ別などで制限回数を変更することができる。
詳細
プロジェクト内全てのAPIへのスロットリング(Global Throttling)
setting.py
REST_FRAMEWORK = {
# throttlingでユーザーによってAPIにアクセスする回数を制限する
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
# For Unauthenticated users
'anon': '10/day',
# For Authenticated users
'user': '50/day'
}
}
views.py
from rest_framework.response import Response
from rest_framework.throttling import UserRateThrottle
from rest_framework.views import APIView
# VeryLimitedViewなど他のViewからも参照されるスロットリング用クラス
class TestThrottle(UserRateThrottle):
rate= '5/day'
class VeryLimitedView(APIView):
# このView(API)では上記のクラスのスロットリング回数を適用
throttle_classes = [TestThrottle]
def get(self, request, format=None):
content = {
'status': 'request was permitted'
}
return Response(content)
選択したViewに一括スロットリング設定(ScopedRateThrottles
)
views.py
class ContactListView(APIView):
throttle_scope = 'scopeA'
...
class ContactDetailView(APIView):
throttle_scope = 'scopeB'
...
class UploadView(APIView):
throttle_scope = 'scopeB'
setting.py
REST_FRAMEWORK = {
# throttlingでユーザーによってAPIにアクセスする回数を制限する
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
# scopeAと設定したviewへのAPI制限回数
'scopeA': '10/day',
# scopeBと設定したviewへのAPI制限回数
'scopeB': '50/day'
}
}