コンテキスト: 指定したユーザーが定期的に (1 日、1 時間、または数分) スター付きリポジトリの全リストを取得したいとします。
これを行うには、少なくとも 2 つの方法があります。
https://api.github.com/users/evereq/starredに対して GET を実行し、「リンク」応答ヘッダーで rel='next' を指定して Url を使用して、次のページの URL を取得します (「next」がなくなるまでこれを行う必要があります)。応答のページは、最後に到達したことを意味します)。それが推奨されるアプローチのようです(Githubによる)。
GET を使用してhttps://api.github.com/users/evereq/starred?page=XXXに 'page' パラメーター (1 から無限) を繰り返し、応答で 0 の結果が得られるまで繰り返します。結果が 0 の場合は、終了します (たとえば、ページ番号の代わりに Github が「ハッシュ」値に移動できるため、推奨されません。Github は、一部の API 操作で既に実行しています)。
ここで、条件付きリクエスト ( https://docs.github.com/en/rest/overview/resources-in-the-rest-api#conditional-requestsを参照) を使用して API の使用を節約することを確認したいとしましょう。制限 (およびトラフィック、世界の木など)。
そのため、たとえば「If-None-Match」をリクエスト ヘッダーに追加し、レスポンス ステータスが 304 (Not Modified) であるかどうかを確認します。そうであれば、前回のリクエストから何も変更されていないことを意味します。それはうまくいきます。
ただし、条件付きリクエストを使用すると、停止するタイミングを検出する方法に関連する上記の 1) および 2) の問題が機能しなくなります。
つまり、アプローチ 1) では、条件付きリクエストを使用すると、リンク レスポンス ヘッダーがまったく取得されません。そのため、既に ETag を持っているページよりも大きなページでもう 1 つの要求を実行し、それが 0 の結果を返すことを確認する必要があります。そうすれば、基本的にGithub APIへの1つのリクエストを「無駄」にします(条件付きリクエストヘッダーが欠落しているため)。
アプローチ 2) と同じです。基本的に、ステータス 304 のすべてのリクエストで 0 の応答があります。繰り返しますが、完了したことを知るには、0 の結果を返す少なくとも 1 つの追加のリクエストを作成する必要があります。
問題は、Github API が Link Response Header を送り返さないという事実 (少なくともステータス 304 を返す ETag を使用したクエリ) で条件付きリクエストを行う場合、ページングを停止するタイミングをどのように知ることができるでしょうか? Github API 実装のバグですか、それとも何か見逃していますか?
最大ページ数がわからないので、いつ停止するかを判断するには、もう 1 つの「無駄な」リクエストを実行し、0 の結果が返されるかどうかを確認する必要があります。
また、応答に「X-Total-Count」などのものが含まれていないため、スター付きリポジトリの合計数をGithubに照会する方法も見つかりません(アドバイスで反復する必要があるページ数を計算できます)。ページ数に単純な計算を使用するのをやめる。
その 1 つの (「終了」) リクエストを保存し、引き続き条件付きリクエストを使用する方法はありますか?
1日1回のリクエストならそんなムダを受け入れてもいいけど、1分に1回リクエストしたらどうなるの?すべての API 使用制限をすぐに使用できます。
アップデート
さて、さらにいくつかのテストの後、「ルール」に従っていることがわかります(ただし、ドキュメントのどこにも見つからないため、そのルールまたは単なる仮定であるかどうかを確認してください):ユーザーが何か新しいものにスターを付けた場合、要求されたすべてのページの結果に含まれるもの以前と比較して ETag 値が異なり、ステータス 304 がなくなりました! つまり、最初のページをリクエストしてステータスを確認するだけで十分です。304 (変更されていない) の場合、次のページをチェックする必要はありません。つまり、どのページも何も変更されていないので完了です。それは正しいアプローチですか、それとも単なる偶然ですか?