LoginSignup
54
49

More than 5 years have passed since last update.

Google APIのBatch Requestの仕組みを理解する

Last updated at Posted at 2016-02-03

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が強制的にに適用されるみたいです。

図に表すとこんな感じになります。
Batch Request概要図.png

実際に送ってみる

Request Bodyはcurlからファイル指定で実行するためにファイルで保管しておきます。

databinary.txt
--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化できるわけではありません。

54
49
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
54
49