Google アナリティクス API リクエストのバッチ処理

Google Developers のブログ投稿での発表のとおり、2019 年 3 月 25 日以降、グローバル HTTP バッチ エンドポイント(www.googleapis.com/batch)は機能しなくなります。対応する API エンドポイント(www.googleapis.com/batch/api/version)に対して同じバッチ リクエストを使用するには、ブログ投稿で説明している手順を行ってください。

ここでは、複数の API 呼び出しを一括で行って、クライアント側の HTTP 接続の回数を減らす方法について説明します。

具体的には、1 件の HTTP リクエストを送信してバッチ リクエストを行う方法を取り上げます。Google クライアント ライブラリを使用してバッチ リクエストを行う場合は、クライアント ライブラリのドキュメントをご覧ください。

概要

クライアントが HTTP 接続を行うたびに、一定量のオーバーヘッドが生じます。Google アナリティクス API では、クライアントが複数の API 呼び出しを 1 つの HTTP リクエストにまとめることができるようにするバッチ処理をサポートしています。

次の場合にはバッチ処理が便利です。

  • ユーザー権限を更新する場合。バッチ リクエストを行ってユーザー権限を更新すると、パフォーマンスが向上するだけでなく、割り当ての面でもメリットがあります。詳しくはユーザー権限 - デベロッパー ガイドをご覧ください。
  • モバイル レポート アプリケーションがオフラインになり、オンラインに復帰した際にまとまったデータ リクエストを行う必要がある場合。
  • サービス アカウント アプリケーションで定期的に複数のレポートを作成する必要がある場合。
  • 一連のカスタム ディメンションまたはカスタム指標の作成を 1 つの HTTP リクエストで済ませたい場合。

いずれの場合も、各呼び出しを個別に送信するのではなく、1 つの HTTP リクエストにまとめることができます。内部リクエストはすべて同じ Google API に送信する必要があります。

1 つのバッチ リクエストに含めることができる呼び出しの上限は 1,000 個です。これ以上の数の呼び出しを行う必要がある場合は、バッチ リクエストを複数使用します。

: Google アナリティクス API のバッチシステムでは、OData バッチ処理システムと同じ構文を使用しますが、意味は異なります。

バッチ リクエストの詳細

バッチ リクエストは、複数の API 呼び出しを 1 つの HTTP リクエストにまとめたもので、API ディスカバリ ドキュメントで指定されている batchPath に送信できます。デフォルトのパスは /batch/api_name/api_version です。このセクションでは、バッチ リクエストの構文について詳しく説明し、最後にを示します。

: リクエストの使用制限のカウントでは、バッチ処理される n 個のリクエストのセットは、1 個のリクエストとしてではなく、n 個のリクエストとしてみなされます。バッチ リクエストは、処理される前に、一連のリクエストに分解されます。

バッチ リクエストの形式

バッチ リクエストは、multipart/mixed コンテンツ タイプを使用した、複数の Google アナリティクス API 呼び出しを含む 1 つの標準的な HTTP リクエストです。このメインの HTTP リクエストを構成する各パートには、ネストされた HTTP リクエストが含まれます。

各パーツはそれぞれ Content-Type: application/http HTTP ヘッダーで始まり、オプションの Content-ID ヘッダーを指定することもできます。ただし、パーツヘッダーはパーツの開始箇所を示すためのものであり、ネストされたリクエストとは分けられています。サーバーが一括リクエストを別々のリクエストにアンラップした後、パーツヘッダーは無視されます。

各パーツのボディは、それ自体が独自の動詞、URL、ヘッダー、ボディを持つ完全な HTTP リクエストになっています。これらの HTTP リクエストには URL のパス部分のみを含める必要があり、完全な URL は、バッチ リクエストでは許可されていません。

外側のバッチ リクエストの HTTP ヘッダー(Content-Type などの Content- ヘッダー以外)はバッチ リクエスト内の各リクエストに適用されます。ある HTTP ヘッダーを外側のリクエストと個々の呼び出しの両方で指定した場合、個々の呼び出しのヘッダー値は外側のバッチ リクエストのヘッダー値を上書きします。個々の呼び出しのヘッダーはその呼び出しにのみ適用されます。

たとえば、ある呼び出しに Authorization ヘッダーを指定した場合、そのヘッダーはその呼び出しにのみ適用されます。Authorization ヘッダーを外側のリクエストに指定した場合、そのヘッダーはすべての呼び出しに適用されます。ただし、各呼び出しに独自の Authorization ヘッダーを指定している場合は、各呼び出しの Authorization ヘッダーで上書きされます。

サーバーがバッチ リクエストを受信すると、外側のリクエストのクエリ パラメータとヘッダー(指定した場合)を各パーツに適用し、各パーツを個別の HTTP リクエストとして処理します。

バッチ リクエストへのレスポンス

サーバーのレスポンスは multipart/mixed コンテンツ タイプを使用した単一の標準 HTTP レスポンスです。各パーツはバッチ リクエスト内の個々のリクエストに対するレスポンスで、リクエストと同じ順序にネストされます。

レスポンスの各パーツは、リクエストのパーツと同様にステータス コード、ヘッダー、ボディを含む完全な HTTP レスポンスになっています。また、リクエストのパーツと同様に、レスポンスの各パーツはパーツの開始箇所を示す Content-Type ヘッダーから始まります。

リクエストのパーツに Content-ID ヘッダーがある場合、対応するレスポンスのパーツには、それに一致する Content-ID ヘッダーが指定されます。レスポンスのパーツのヘッダーは、以下の例に示すように、元の値の先頭に文字列 response- が付いた値となります。

: サーバーはバッチ リクエスト内の呼び出しを順番どおりに処理するとは限らないため、指定した順序で実行されると想定しないでください。2 つの呼び出しを特定の順序で実行したい場合は、1 つのバッチ リクエストで送信することはできません。代わりに、最初の呼び出しを送信してレスポンスが返ってきてから、2 番目の呼び出しを送信します。

次の例は、Google アナリティクス API でのバッチ処理の使い方を示しています。

バッチ リクエストの例

POST /batch/analytics/v3 HTTP/1.1
Host: www.googleapis.com
Content-length: 731
Content-type: multipart/mixed; boundary=batch_0123456789
Authorization: Bearer ya29.5gFZooleNoSpGqYOOF0eFciUGz1x26k9GagZoW7HJCogWlCoNOotxlZPo7bDbwo1ykDq
--batch_0123456789
Content-Type: application/http
Content-ID: 
Content-Transfer-Encoding: binary

POST https://www.googleapis.com/analytics/v3/management/accounts/XXXXXX/webproperties/UA-XXXXXX-1/customDimensions
Content-Type: application/json
Content-Length: 68

{
 "name": "Campaign Group",
 "scope": "SESSION",
 "active": true
}

--batch_0123456789
Content-Type: application/http
Content-ID: 
Content-Transfer-Encoding: binary

POST https://www.googleapis.com/analytics/v3/management/accounts/XXXXXX/webproperties/UA-XXXXXX-1/customDimensions
Content-Type: application/json
Content-Length: 67

{
 "name": "Campaign Type",
 "scope": "SESSION",
 "active": true
}

--batch_0123456789--

バッチ レスポンスの例

次に示すのは、前のセクションのサンプル リクエストに対するレスポンスです。

HTTP/1.1 200 OK
Content-length: 1876
X-xss-protection: 1; mode=block
X-content-type-options: nosniff
Expires: Wed, 02 Sep 2015 21:36:35 GMT
Vary: Origin,X-Origin
Server: GSE
Cache-control: private, max-age=0
Date: Wed, 02 Sep 2015 21:36:35 GMT
X-frame-options: SAMEORIGIN
Content-type: multipart/mixed; boundary=batch_KDU-RkhYyNI_AAkR9Jc5Z_Q
--batch_KDU-RkhYyNI_AAkR9Jc5Z_Q
Content-Type: application/http
Content-ID: 

HTTP/1.1 200 OK
ETag: "o-85COrcxoYkAw5itMLG4AKNpMY/L-Y_3uM9BpST8Sea-SJDRQ7N7vE"
Content-Type: application/json; charset=UTF-8
Date: Wed, 02 Sep 2015 21:36:35 GMT
Expires: Wed, 02 Sep 2015 21:36:35 GMT
Cache-Control: private, max-age=0
Content-Length: 548

{"kind":"analytics#customDimension","id":"ga:dimension18","accountId":"XXXXXX","webPropertyId":"UA-XXXXXX-1","name":"Campaign Group","index":18,"scope":"SESSION","active":true,"created":"2015-09-02T21:36:34.143Z","updated":"2015-09-02T21:36:34.143Z","selfLink":"https://www.googleapis.com/analytics/v3/management/accounts/XXXXXX/webproperties/UA-XXXXXX-1/customDimensions/ga:dimension18","parentLink":{"type":"analytics#webproperty","href":"https://www.googleapis.com/analytics/v3/management/accounts/XXXXXX/webproperties/UA-XXXXXX-1"}}
--batch_KDU-RkhYyNI_AAkR9Jc5Z_Q
Content-Type: application/http
Content-ID: 

HTTP/1.1 200 OK
ETag: "o-85COrcxoYkAw5itMLG4AKNpMY/VN-21fLS1T0Qko3pHEB5fi8vYJ8"
Content-Type: application/json; charset=UTF-8
Date: Wed, 02 Sep 2015 21:36:35 GMT
Expires: Wed, 02 Sep 2015 21:36:35 GMT
Cache-Control: private, max-age=0
Content-Length: 547

{"kind":"analytics#customDimension","id":"ga:dimension19","accountId":"XXXXXX","webPropertyId":"UA-XXXXXX-1","name":"Campaign Type","index":19,"scope":"SESSION","active":true,"created":"2015-09-02T21:36:35.099Z","updated":"2015-09-02T21:36:35.099Z","selfLink":"https://www.googleapis.com/analytics/v3/management/accounts/XXXXXX/webproperties/UA-XXXXXX-1/customDimensions/ga:dimension19","parentLink":{"type":"analytics#webproperty","href":"https://www.googleapis.com/analytics/v3/management/accounts/XXXXXX/webproperties/UA-XXXXXX-1"}}
--batch_KDU-RkhYyNI_AAkR9Jc5Z_Q--

クライアント ライブラリ

バッチ処理を実装する方法については、言語別に用意されている以下のクライアント ライブラリ ガイドをご覧ください。

バッチ処理と Google アナリティクスの割り当て

バッチ処理を行うと、多くの HTTP リクエストを作成する際のオーバーヘッドを回避できますが、バッチ リクエスト内の各 Google アナリティクス API リクエストは、プロジェクトあたりの 1 日の割り当てに対してカウントされます。デフォルトでは、プロジェクトあたり 1 日 50,000 件のリクエストに制限されており、バッチ処理を行ってもこの割り当てに対するカウントを 減らすことはできません。

ユーザー権限の書き込みリクエスト(delete、insert、update)のバッチ処理のみを例外として、他のすべての場合でリクエストの上限が適用されます。たとえば、Core Reporting API はビュー(旧プロファイル)あたりの同時リクエスト数が 10 件に制限されており、バッチ処理を行ってもこの制限に対するカウントを減らすことはできません。

Management API の書き込みリクエストProvisioning API の書き込みリクエストについては、アカウント ID ごとの 1 秒あたりのクエリ数(QPS)が 1.5 件までに制限されます。このため、こうした書き込みリクエストをバッチ処理しても、パフォーマンスの向上は達成できない場合があります。