MENU

GASでAPIの応答ヘッダーを確認する

当ページのリンクには広告(PR)が含まれていることがあります。
GASでAPIの応答ヘッダーを確認する。API の応答、ヘッダーを読む、コードと対応付けの処理例。

APIが429を返したとき、本文のエラーだけでは、いつ次の取得を試せばよいか分からない場合があります。HTTPの応答ヘッダーにはRetry-AfterやContent-Typeなど、本文とは別の情報が入ります。ステータスと組にして確認します。

GASのHTTPResponseではgetAllHeadersで応答ヘッダーを読み取れます。同じ項目に複数の値がある場合は配列になるため、常に1つの文字列だと思って処理しないようにします。ログには必要な項目だけを選びます。

目次

本文とヘッダーを別々に読む

getResponseCodeはHTTPステータス、getContentTextは本文、getAllHeadersはヘッダーを返します。どの情報を表示しているかを名前で分けると、本文のJSONにあるstatusという値とHTTPコードを取り違えにくくなります。

公式のHTTPResponse資料は、複数の値を持つヘッダーを配列として返すことを説明しています。ヘッダー名は返された表記の大文字小文字が一定とは決めず、照合用の名前を小文字にそろえて扱います。

すべてのヘッダーをそのままログへ出すと、Cookieなどの不要な情報も記録する可能性があります。今回はContent-TypeとRetry-Afterだけを取り出し、本文も保存しません。必要になった項目を個別に追加する形にします。

必要な項目を配列へそろえるコード

実際の通信をしなくても形を確認できるよう、下の実行例は架空の応答オブジェクトを使います。実応答でも同じgetResponseCodeとgetAllHeadersを呼ぶ関数です。

function summarizeResponseHeaders(response) {
  const normalized = Object.create(null);
  const headers = response.getAllHeaders();
  Object.keys(headers).forEach(function (name) {
    const key = name.toLowerCase();
    if (!['content-type', 'retry-after'].includes(key)) return;
    const value = headers[name];
    const values = Array.isArray(value) ? value : [value];
    normalized[key] = (normalized[key] || []).concat(values.map(String));
  });
  return {
    httpStatus: response.getResponseCode(),
    contentType: normalized['content-type'] || [],
    retryAfter: normalized['retry-after'] || []
  };
}

function previewResponseHeaders() {
  const sample = {
    getResponseCode: () => 429,
    getAllHeaders: () => ({
      'Content-Type': 'application/json', 'retry-after': ['30'],
      'Set-Cookie': '掲載しない架空の値'
    })
  };
  console.log(JSON.stringify(summarizeResponseHeaders(sample)));
}

結果はhttpStatus:429、contentType:["application/json"]、retryAfter:["30"]です。Set-Cookieは結果に入りません。文字列と配列を同じ形にそろえるので、後続で要素数を確認できます。

Retry-Afterをそのまま待機秒数にしない

RFC 9110にあるように、Retry-Afterは秒数だけでなくHTTP日時で示される場合があります。parseIntをかけるだけでは、日時の文字列を待機時間として扱えません。形式を判定し、使用するAPIの再試行条件と合わせて解釈します。

複数の値が返った場合も、先頭だけを根拠なく採用しません。中継するサーバーなどの影響を含め、公式のAPI資料と実際の応答を確認します。値がない場合は0秒とみなさず、「情報なし」として別に扱います。

ヘッダーを読めたことと、要求を再送してよいことも別です。投稿作成やメール送信の結果が不明なら、送信先に結果があるかを先に調べます。読み取りの取得と、重複で困る更新を同じ再試行処理に入れないようにします。

実応答へつなぐときの確認

UrlFetchApp.fetchで失敗ステータスも調べたい場合は、muteHttpExceptions:trueを指定する方法があります。ただし通信自体の例外まで、すべてHTTPResponseへ変わるわけではありません。応答を受け取った場合と、通信例外を分けます。

muteHttpExceptionsは公式のUrlFetchAppで確認できます。掲載コードはローカルの代用応答で、大文字小文字、配列、未存在、不要ヘッダーの除外を確認しました。実際のAPI通信や待機・再送は実行していません。

APIキーをログへ出さない準備は設定の保存方法、失敗箇所の確認はGASの実行履歴と合わせて使えます。

この記事を書いた人

Watanabeのアバター Watanabe サイト運営者

2020年よりブログ開始。
SEOが思いのほか性にあっていたようで現在に至る。
モットーは「勝率の高い選択をする」
AIは活用するが吉、最後は人間が息を吹き込む。
アートと科学を追求し、日々精進。
―――
収益:6~7桁をウゴウゴ。
サイト:ペラサイト~中規模サイトまで運営中。
案件:1000円以上の案件をメインに取組中。
打ち手:ブラックSEO~ホワイトSEOまで
―――

目次