【入門編】 HTTPヘッダーによるレートリミット通知(X-RateLimit-Limit, Remaining, Reset) – Web APIアーキテクチャ・データ連携実践ガイド

皆さん、こんにちは!ネットワークプロトコルスペシャリストの〇〇です。

Webの世界は、まるで巨大な都市のよう。その中で、さまざまなサービスが連携し、私たちの日々の生活を便利にしていますよね。その連携の要となっているのが、「API」という存在です。

今日は、そんなWeb APIをみんなで気持ちよく使うための、とっても大切なお約束事、その中でも特に「サーバーからの優しいお知らせ」について深掘りしていきましょう。具体的には、APIの利用制限を教えてくれるHTTPヘッダー、X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset に焦点を当てて解説します。

「ヘッダー?なんだか難しそう…」と思った方もご安心を!郵便配達の流れや、私たちが普段利用する身近なサービスに例えながら、一歩ずつ丁寧に紐解いていきますからね。

—

呼びすぎ注意!APIと「ちょっと待って!」の関係

まず、Web APIがどんなものか、イメージしてみましょう。
Web APIは、例えるなら「お店の窓口」のようなものです。私たちがスマートフォンのアプリで天気予報を見たり、地図アプリで経路を検索したりするとき、アプリの裏側では、それぞれのサービスが提供する「窓口」に対して、「今日の天気は?」「ここから目的地までの道順は?」と問い合わせをしているんです。この「問い合わせ」がAPIリクエストですね。

みんなで使うからこそ必要なお約束事「レートリミット」

さて、この「お店の窓口」、もし誰か一人が一日中、何千回、何万回も立て続けに問い合わせをしたらどうなるでしょう?
そう、窓口の担当者さんはパンクしてしまいますよね。他のお客さんも、問い合わせるまでに長い時間待たされることになり、みんなが不便を感じてしまいます。

Web APIも全く同じです。
サーバーは、たくさんのユーザーからのリクエストを処理しています。もし特定のユーザーが短時間のうちにあまりにも多くのリクエストを送ると、サーバーに過度な負荷がかかり、最悪の場合、サービスが停止してしまうこともあります。そうなると、他のすべてのユーザーがAPIを使えなくなってしまいますよね。

そこで登場するのが「レートリミット(Rate Limit)」という仕組みです。
これは、「短時間のうちにAPIを呼び出す回数に上限を設ける」というお約束事。サーバーの安定稼働を守り、すべてのユーザーが公平にAPIを利用できるようにするための、とっても大切なルールなんです。

サーバーからの「お知らせ」が肝心!

このレートリミット、ただ「制限します!」とだけ言われても困りますよね。
「あと何回まで使えるの?」「次に使えるようになるのはいつ?」といった情報が分かれば、私たちクライアント側も、APIに無理な負荷をかけずに、スマートに利用できます。

この「あと何回までOK?」という、サーバーからの優しいお知らせを伝えるのが、今日ご紹介するHTTPヘッダーたちなんです!HTTPヘッダーは、APIのレスポンス(サーバーからの返事)に添えられた「メッセージカード」のようなものだと考えてください。

—

主役登場!3つの「X-RateLimit」ヘッダーを徹底解説

APIを利用する際には、サーバーからの返事(レスポンス)の中に、現在のレートリミットに関する情報がメッセージカードとして添えられています。それが X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset の3つです。

これらは、特定のAPIサービスが独自に提供しているヘッダーなので、頭に X- が付いていることが多いです(最近では標準化された RateLimit- プレフィックスが使われることもありますが、X-RateLimit- も広く使われています)。

一つずつ、具体的に見ていきましょう!

1. X-RateLimit-Limit: 「制限の上限」を教えてくれるカード

まず一つ目は X-RateLimit-Limit です。

これは「あなた(のIPアドレスやAPIキー)が、このAPIを一定期間内に最大何回まで利用できますよ」という、上限回数を示すメッセージカードです。

例えるなら、郵便局の窓口で「本日、お一人様につき荷物の受付は最大10個までです!」と書かれた貼り紙のようなものですね。この数字は、APIを提供する側によって決められていて、APIの種類や利用プランによって変わることがあります。

X-RateLimit-Limit: 60

この場合、「このAPIは、1分間に最大60回までリクエストできますよ」といった意味合いになります。

2. X-RateLimit-Remaining: 「残りの回数」を教えてくれるカード

次に X-RateLimit-Remaining です。

これは「現在、あなたに残されているAPIの利用可能回数はあと何回ですよ」というメッセージカードです。

郵便局の例で言えば、あなたがすでに荷物を3個送っていたら、「あと7個まで送れますよ」と教えてくれるようなものです。この数字は、APIを1回呼び出すごとに減っていきます。

X-RateLimit-Remaining: 57

先ほどの X-RateLimit-Limit: 60 のAPIを3回使った後だと、このような値になるわけですね。この値を見れば、「あっ、あと少ししか使えないから、ちょっと休憩しようかな」と判断できます。

3. X-RateLimit-Reset: 「いつリセットされるか」を教えてくれるカード

そして最後が X-RateLimit-Reset です。これが一番重要かもしれません。

これは「残りの利用回数が、いつになったら上限までリセット(回復)されますよ」というメッセージカードです。

郵便局の例で言えば、「明日の朝9時には、また上限の10個まで荷物を受け付けられるようになりますよ」というお知らせと似ています。

この値は、通常「Unixタイムスタンプ」という形式で表現されます。
「Unixタイムスタンプ?」と聞くと難しそうですよね。でも大丈夫!これは、1970年1月1日0時0分0秒(UTCという世界標準時)からの経過秒数を数えた、ただの通し番号だと思ってください。世界中のコンピューターが共通で時間を扱うための、とても便利な仕組みなんです。

たとえば、1678886400 という値であれば、それは 2023年3月15日0時0分0秒 (UTC) を指す、といった具合です。

X-RateLimit-Reset: 1678886400

この値を確認すれば、「あと何秒待てば、またAPIをフルで使えるようになるか」が分かります。クライアント側で、この情報をもとに「しばらく待ってからリクエストを再開する」といった賢い処理ができるようになるわけです。

—

実際にAPIを使ってみよう!ヘッダーを確認する

では、実際にAPIを叩いてみて、これらのヘッダーがどのように返ってくるのか見てみましょう。
ここでは、curl というコマンドラインツールを使います。これは、Webサーバーと通信するための、とても便利なツールです。

例えば、GitHubのAPIを叩いてみましょう(認証なしの場合、レートリミットは低めに設定されています)。

# GitHubのAPIを叩いて、レスポンスヘッダーだけを表示する
curl -i https://api.github.com/users/octocat

このコマンドを実行すると、以下のようなレスポンスが返ってきます(一部抜粋)。

HTTP/2 200 
server: GitHub.com
date: Wed, 15 Mar 2023 09:00:00 GMT
# ... その他のヘッダー ...
x-ratelimit-limit: 60        # 1時間あたり最大60リクエスト
x-ratelimit-remaining: 59    # 残り59リクエスト
x-ratelimit-reset: 1678886400 # UTCで2023年3月15日10:00:00にリセット
cache-control: public, max-age=60, s-maxage=60
# ... その他のヘッダー ...

{
  "login": "octocat",
  "id": 583231,
  # ... レスポンスボディ ...
}

注目していただきたいのは、x-ratelimit-limit、x-ratelimit-remaining、x-ratelimit-reset の行です。
この例では、

  • x-ratelimit-limit: 60: 1時間あたり60回までAPIを叩ける
  • x-ratelimit-remaining: 59: 残り59回叩ける
  • x-ratelimit-reset: 1678886400: Unixタイムスタンプ 1678886400 (この例では 2023年3月15日10:00:00 UTC と仮定)になるとリミットがリセットされる

ということが分かりますね。

—

クライアント側でどう使う? レートリミットを考慮した実装のヒント

これらのヘッダー情報は、APIを使う私たちクライアント側で、とても重要な役割を果たします。

1. 429 Too Many Requests エラーへの備え

もしレートリミットを超えてAPIを叩いてしまうと、サーバーは 429 Too Many Requests というエラーコードを返してきます。これは「ごめんなさい、ちょっと呼び出しすぎです!」という、サーバーからの明確な拒否のサインです。

このエラーを受け取ったら、闇雲に再試行するのではなく、X-RateLimit-Reset ヘッダーの情報を確認して、リセットされるまで待機するのが最もスマートな対応です。

2. X-RateLimit-Reset を使った賢い待機処理(バックオフ)

Pythonを使って、この待機処理を実装する簡単な例を見てみましょう。

import requests
import time
import datetime

def call_api_with_ratelimit_handling(url):
    while True:
        response = requests.get(url)

        # レスポンスヘッダーからレートリミット情報を取得
        limit = response.headers.get('X-RateLimit-Limit')
        remaining = response.headers.get('X-RateLimit-Remaining')
        reset_timestamp = response.headers.get('X-RateLimit-Reset')

        print(f"APIリクエスト結果: {response.status_code}")
        print(f"  X-RateLimit-Limit: {limit}")
        print(f"  X-RateLimit-Remaining: {remaining}")
        print(f"  X-RateLimit-Reset: {reset_timestamp}")

        if response.status_code == 429:
            # 429エラーの場合、リセットされるまで待機する
            if reset_timestamp:
                current_time = int(time.time()) # 現在のUnixタイムスタンプ
                wait_time = int(reset_timestamp) - current_time

                if wait_time > 0:
                    print(f"429エラーを受信しました。リセットまで {wait_time} 秒待機します...")
                    time.sleep(wait_time + 1) # 念のため1秒多めに待つ
                    print("待機終了。再試行します。")
                    continue # ループの最初に戻って再試行
                else:
                    # reset_timestampが過去の場合(理論上はありえないが念のため)
                    print("reset_timestampが現在時刻以前です。短時間待機して再試行します。")
                    time.sleep(5) # 5秒待って再試行
                    continue
            else:
                # reset_timestampがない場合、一般的なバックオフ戦略
                print("X-RateLimit-Resetヘッダーがありません。5秒待機して再試行します。")
                time.sleep(5)
                continue
        elif response.status_code == 200:
            # 成功した場合の処理
            print("APIリクエストが成功しました!")
            print(response.json()) # JSON形式のレスポンスボディを表示
            break # ループを抜ける
        else:
            # その他のエラーの場合
            print(f"その他のエラーが発生しました: {response.status_code}")
            break # ループを抜ける

# 実際のAPIエンドポイントに置き換えてください
# GitHub API (認証なしの場合、レートリミットは低め)
api_url = "https://api.github.com/users/octocat" 

call_api_with_ratelimit_handling(api_url)

このコードでは、429 Too Many Requests が返ってきた場合、X-RateLimit-Reset の値を使って、リミットが解除される正確な時間まで待機する、という処理を実装しています。これにより、サーバーに余計な負荷をかけずに、スマートにAPIを利用し続けることができます。

—

まとめ:APIはみんなで使うもの、だからスマートに!

Web APIのレートリミット通知ヘッダー、X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset。これらは、単なる数字の羅列ではありません。

APIを提供するサーバーからの「あなたに今、どれくらいのリソースを提供できますよ。そして、次にいつまたたくさん使えるようになりますよ」という、ユーザーへの配慮と、Webエコシステム全体を守るための大切なメッセージなんです。

これらのヘッダーを理解し、自分のプログラムに組み込むことで、皆さんのアプリケーションは、APIに対してより「お行儀よく」、そして「賢く」振る舞うことができるようになります。それは、サーバー管理者にとっても、他のAPI利用者にとっても、そして何より、あなたのアプリケーションにとっても良いこと尽くしですよね。

さあ、今日学んだ知識を活かして、皆さんもスマートなAPI連携の世界へ飛び込んでみましょう!
私もパケットの海を泳ぎながら、皆さんのWeb開発を応援しています!

コメント

タイトルとURLをコピーしました