2018/3/26
Discontinuing support for JSON-RPC and Global HTTP Batch Endpoints
Batch Request のエンドポイントが変わるようです。
お使いの方はブログの内容をみて対応しましょう。(2019/3/25までに)
www.googleapis.com/batch
↓↓↓
www.googleapis.com/batch/<api>/<version>.
Google APIにはBatch RequestというAPIを複数実行するための仕組みがあります。
Batch Requestを使用することでAPI発行側は実行速度の向上になります。
リクエスト数が減ることによりGoogle側の負荷も減るはずなので
基本的にデメリットはないという認識です。
複数APIを実行する際はBatch Requestを積極的に使っていきましょう。
また、BatchRequestの仕組みはメール送信やWebの添付ファイル送信でも似たような仕組みが使われています。
Google APIなんて使わないという方も知っておいて損はないかと思います。
@本記事はBatch Requestの仕組みの理解を目的にしたものです。
実際に使用する際は各種Google提供のライブラリに用意されていると思いますのでそちらを利用することをおすすめします。
https://developers.google.com/discovery/libraries
前提
アクセストークンの取得まではこちらの記事を参照してください
http://qiita.com/shin1ogawa/items/49a076f62e5f17f18fe5
本記事では以下のようにACCESS_TOKENは環境変数に入れて実行しています。
export ACCESS_TOKEN=ya29.fAIcwrExRp....
普通にAPIを発行
バッチリクエスト化する前にまず普通にAPIを実行してみます。
APIの送り方
- URL
- 各種APIによる
- Method
- 各種APIによる 主にGET、POST、PATCH、DELETE
- Authorization Header
- Authorization: Bearer {ACCESS_TOKEN}
- Body
- POSTやPATCHで使用 主にJSON
Drive APIを使用してファイルの一覧を取得する例
Request
curl https://www.googleapis.com/drive/v3/files -H "Authorization: Bearer $ACCESS_TOKEN"
Response
{
"kind": "drive#fileList",
"files": [
{
"kind": "drive#file",
"id": "1q5eHxwMySsmnAGV4x831txwWVZ6DDD1CmwCP4QcRBAs",
"name": "ドキュメント001",
"mimeType": "application/vnd.google-apps.document"
},
{
"kind": "drive#file",
"id": "1xXnBefD_jDcjZ-vEb50LO7xS01-AsHgdpKioQLegHrQ",
"name": "スプレッドシート001",
"mimeType": "application/vnd.google-apps.spreadsheet"
},
{
"kind": "drive#file",
"id": "1NT8jIxP_NKbzgdJyQ4FPJTFaiAROmKZmIPq_TBS8wJY",
"name": "プレゼンテーション001",
"mimeType": "application/vnd.google-apps.presentation"
}
]
}
Batch Requestに変換
実際に複数にすると長くなってわかりづらいので1件だけのBatch Requestにします。
※1件がわかれば複数も簡単です。
Batch Requestの送り方
Batch Requestは以下のように送る必要があります。
- URL
- https://www.googleapis.com/batch
- Method
- POST
- Authorization Header
- Authorization: Bearer {ACCESS_TOKEN}
- Content-Type Header
- Content-Type: multipart/mixed; boundary=BOUNDARY
- Request Body
- ここにそれぞれのリクエストを記載します。詳細は後述。
Content-Typeをmultipart/mixedにして「リクエストを複数含みます」と教えてあげます。
boundaryは「それぞれのリクエストをこの文字で区切ります」という意味です。本記事では"BOUNDARY"という文字列を指定します。
Request Body
フォーマットとしては以下のとおりです。
--{BOUNDARY}
Content-Type: application/http
Content-ID: xxx
HTTP情報
--{BOUNDARY}--
HTTPリクエストを表すContent-Typeとそれぞれのリクエストに対するContent-IDを指定します。
Content-IDはなんでもいいですが被らないようにしてください。また、レスポンスを解析するときに使います。(私は主キーとなりうる値を設定することが多いです)
複数送信するHTTPのRequest情報がRequest Bodyに入る形になります。
なお、この際にAuthorizationは外します。(入れても効かなかったです)
Batch Requestに設定したAuthorizationが強制的にに適用されるみたいです。
実際に送ってみる
Request Bodyはcurlからファイル指定で実行するためにファイルで保管しておきます。
--BOUNDARY
Content-Type: application/http
Content-ID: 1
GET https://www.googleapis.com/drive/v3/files
--BOUNDARY--
Request
curl https://www.googleapis.com/batch -H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-Type: multipart/mixed; boundary=BOUNDARY" --data-binary @databinary.txt
Response
--batch_oysSsPRlgxc_AAP4j4WrTtE
Content-Type: application/http
Content-ID: response-1
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Date: Tue, 02 Feb 2016 21:40:32 GMT
Expires: Tue, 02 Feb 2016 21:40:32 GMT
Cache-Control: private, max-age=0
Content-Length: 610
{
"kind": "drive#fileList",
"files": [
{
"kind": "drive#file",
"id": "1q5eHxwMySsmnAGV4x831txwWVZ6DDD1CmwCP4QcRBAs",
"name": "ドキュメント001",
"mimeType": "application/vnd.google-apps.document"
},
{
"kind": "drive#file",
"id": "1xXnBefD_jDcjZ-vEb50LO7xS01-AsHgdpKioQLegHrQ",
"name": "スプレッドシート001",
"mimeType": "application/vnd.google-apps.spreadsheet"
},
{
"kind": "drive#file",
"id": "1NT8jIxP_NKbzgdJyQ4FPJTFaiAROmKZmIPq_TBS8wJY",
"name": "プレゼンテーション001",
"mimeType": "application/vnd.google-apps.presentation"
}
]
}
--batch_oysSsPRlgxc_AAP4j4WrTtE--
リクエストを送った時と同じようにGoogleが設定したBOUNDARYが設定されていますのでクライアント側はBOUNDARYで区切って処理していきます。
この時のContent-IDはresponse-{リクエスト時に送ったContent-ID}
という形になります。
この値によりどのリクエストのレスポンスかどうかの判断が可能です。(リクエストと同じ順番で返ってくるかもしれませんがそのほうが安全だと思います)
おまけ(POSTリクエスト例)
Content-Lengthがなくても一応通るようです。
※ちなみにこのリクエストは1つ目で権限を追加して、2つ目で権限の一覧を抜いていますが、2つ目の権限一覧の結果には1つ目のリクエストで追加した権限は反映されていません。
バッチリクエストは順番を保証しないため順番をあてにしたリクエストはNGです。
--BOUNDARY
Content-Type: application/http
content-id: 1
POST /drive/v3/files/17zoAl-wCvZdtvXLyW9lnlwODU77golDR_CcLK1mrgiE/permissions
Content-Type: application/json; charset=UTF-8
{
"emailAddress": "user1@howdylikes.jp",
"role": "writer",
"type": "user"
}
--BOUNDARY
Content-Type: application/http
content-id: 2
GET /drive/v3/files/1428x4m9MSiMerQizvKXWbKhXh_a3Ye6lHhUl0HwjkEw/permissions
--BOUNDARY--
その他
リクエスト上限
APIの種別によりまちまちですのでリファレンスを参照してください。
Driveは100 https://developers.google.com/drive/v3/web/batch
Calendarは50 https://developers.google.com/google-apps/calendar/batch
Directoyは1000 https://developers.google.com/admin-sdk/directory/v1/guides/batch
注意点
すべてのAPIがBatch Request化できるわけではありません。