こんにちは!インフラアーキテクトの私です。日々、世界中を駆け巡るパケットの海を見つめていると、「もっとシステムを優しく、美しく作れないものか」と考えることがよくあります。
さて、Web APIの開発や連携で避けて通れないのが「レートリミット(回数制限)」の仕組みです。
「なんだか難しそうな英語のヘッダーが出てきたぞ…」と身構えてしまう初学者の方もいらっしゃるかもしれませんが、安心してください!一歩ずつ、身近な例えから紐解いていきましょう。
—
1. 郵便局の窓口で学ぶ「レートリミット」の基本
突然ですが、街の郵便局を想像してみてください。
そこには「1人あたり、1日に送れる荷物は最大50個まで」というルールがあったとします。
もし、あなたが窓口にドカンと100個の荷物を持ち込んだらどうなるでしょうか?
郵便局の窓口はパンクしてしまい、後ろに並んでいる一般の利用客まで大迷惑ですよね。だから、郵便局員さんはこう告げます。
「申し訳ありませんが、本日のあなたの荷物受付枠はすでに上限に達しました。明日また来てくださいね」
Web APIの世界もこれと全く同じです。
サーバーという「郵便局の窓口」が、特定のクライアント(アプリやWebサイト)からあまりにも大量のリクエスト(荷物)を受け取ると、システム全体がダウンしてしまいます。それを防ぐために「あなた、今日はもう〇回までしかアクセスしちゃダメですよ」と制限をかける仕組み、それが「レートリミット」です。
—
2. 制限を優しく伝える「3つの暗号」の正体
では、APIサーバーは私たちクライアントに、どうやってその制限状況を伝えているのでしょうか?
ここで登場するのが、今回の主役である以下の3つのHTTPヘッダーです。なんだか呪文のように見えますが、実はとってもシンプルな「お知らせメモ」なんですよ。
1. X-RateLimit-Limit(リミットの全体量)
2. X-RateLimit-Remaining(残り残高)
3. X-RateLimit-Reset(復活する時間)
先ほどの郵便局の例えで、この3つのメモを分かりやすく翻訳してみましょう!
X-RateLimit-Limit:あなたに与えられた「1日のトータルの枠」
「あなたは今日、最大で 100回 までAPIを使っていいですよ」という、最初に決められた上限の数字が入ります。いわばクレジットカードの利用枠のようなものです。
X-RateLimit-Remaining:財布の中の「残りの使える回数」
「今日使える枠のうち、今の時点で あと35回 残っていますよ」という、リアルタイムの残り回数です。APIを1回叩くごとに、この数字が 34、33 と減っていきます。
X-RateLimit-Reset:制限がリセットされる「タイムリミット(復活の呪文)」
「今減ってしまった残り回数が、次にゼロから全回復するのは (何月何何日の何時何分、あるいはそれからの秒数) ですよ」という、未来の時間を指しています。
「おっ、〇時になればまた窓口が空いてフルで使えるようになるんだな!」とクライアント側が予測できるわけですね。
—
3. レスポンスヘッダーの実際の姿を見てみよう
実際に、APIサーバーが返してくるHTTPレスポンスの裏側を覗いてみましょう。ブラウザの開発者ツールや、ターミナルで curl コマンドを叩いたときに、以下のようなヘッダー情報がこっそり添えられています。
HTTP/1.1 200 OK
Content-Type: application/json
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1711958400
このレスポンスが意味しているのは、こんな状態です。
- 「このAPIは、1時間あたり最大 60回 までアクセスできます (
X-RateLimit-Limit: 60)」 - 「今のあなたの残り回数はあと 58回 です (
X-RateLimit-Remaining: 58)」 - 「次に制限がチャリンとリセットされるのは、UNIX時間で
1711958400(日本時間の某日某時)です (X-RateLimit-Reset: 1711958400)」
もし、この Remaining が 0 になってしまった後に無理やりアクセスしようとすると、サーバーは怒って 429 Too Many Requests というステータスコードと共に、「ちょっと落ち着いて!」とエラーを返してくる仕組みになっています。
—
4. クライアント側(アプリ側)はどう実装すべき?
インフラやバックエンドだけでなく、フロントエンドやアプリを開発するエンジニアにとっても、このヘッダーを読み取ることは非常に重要です。
例えば、Pythonを使ってAPIを叩くコードを書く場合、以下のようにこれらのヘッダーを優しく見守る(ハンドリングする)ロジックを組み込むのが「美しいAPI連携」の秘訣です。
import time
import requests
# APIのエンドポイントURL
url = "https://api.example.com/v1/data"
response = requests.get(url)
# レスポンスヘッダーからレートリミット情報を取得する
# (ヘッダーが存在しない場合も考慮して .get() や安全な型変換を行うのがプロの技です)
limit = response.headers.get("X-RateLimit-Limit")
remaining = response.headers.get("X-RateLimit-Remaining")
reset_time = response.headers.get("X-RateLimit-Reset")
print(f"全体の上限: {limit}")
print(f"現在の残り: {remaining}")
# もし残り回数が少なくなってきたら、少し処理をスロットリング(減速)する
if remaining is not None and int(remaining) < 5:
print("⚠️ 警告: APIの残り利用枠が少なくなっています!")
# 必要に応じて処理を一時停止するなどの優しさをアプリに持たせましょう
このように、サーバーから送られてくる「お告げ(ヘッダー)」をしっかり受け止め、アプリ側で自発的にアクセスのペースを落とすことを、現場では「優しさのあるポーリング」や「スマートな制御」と呼んだりします。
—
おわりに
今回は、APIのレートリミットを支える X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset の3つのヘッダーについて紐解いてみました。
難解に思えるネットワークの仕様も、身近な「窓口の行列」や「お小遣いの残り」に置き換えてみると、途端に愛着が湧いてきませんか?
美しいAPI設計とは、ただデータを返すだけでなく、「今、クライアントがどんな状態にいるのか」を優しく、正確に伝えるコミュニケーションの場でもあります。
ぜひ皆さんの次の開発プロジェクトでも、この心遣いのあるヘッダー設計を取り入れてみてくださいね。それでは、また次回の深淵でお会いしましょう!
コメント