Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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

howdy39
heyinc corporate engineer https://techthetoaster.booth.pm/
https://howdy39.dev/
storesjp
インターネットビジネスの企画・開発・運営、マーケティング、プロモーション、コンテンツの企画・制作
https://about.stores.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした