发送批量请求

本文档介绍了如何对 JSON API 调用进行集中批处理以减少客户端在访问 Cloud Storage 时必须建立的 HTTP 连接数量。

概览

客户端建立的每个 HTTP 连接都会产生一定的开销。Cloud Storage JSON API 支持批处理,这样您的客户端就可以将多次 API 调用组合为一个 HTTP 请求。

在以下示例情况下,您可能需要使用批处理:

  • 更新多个对象的元数据,例如权限。
  • 删除多个对象。

在上述每种情况下,您都可以将这些调用组合成一个 HTTP 请求,而不是单独发送每次调用。请注意,所有内部请求都必须发送到 Cloud Storage JSON API。

单个批处理请求中包含的调用不应超过 100 次。如果您需要的调用次数超过此值,请使用多个批处理请求。批处理请求总载荷必须小于 10MB。

批量详情

批量请求就是将多个 API 调用进行合并而形成的一个 HTTP 请求,您可以将此请求发送到 API 发现文档中指定的 batchPath。Cloud Storage 的路径是 /batch/storage/v1。本部分详细介绍了批处理语法,随后还会提供一个示例

批量请求的格式

批处理请求是一个包含多个 Cloud Storage JSON API 调用的标准 HTTP 请求。此主请求使用 multipart/mixed 内容类型。主 HTTP 请求中包含多个部分,每个部分均包含一个嵌套的 HTTP 请求。

各个部分都以其自身的 Content-Type: application/http 标头开头。 各部分还可以有一个可选的 Content-ID 标头。这些标头用于标记各部分的开头,但它们与嵌套的 HTTP 请求无关。这意味着,在服务器将批处理请求拆分为单独的请求后,该部分的标头会被忽略。

各个部分的正文本身是一个完整的 HTTP 请求,各自有专用的动词、网址、标头和正文。这些 HTTP 请求只能包含网址的路径部分;完整网址可能会有未定义的行为。

外部批处理请求的 HTTP 标头还应用于每个嵌套请求,但 Content-Type 之类的 Content- 标头除外。但是,如果您在外部请求和嵌套请求中都指定了特定的 HTTP 标头,则嵌套请求的标头值会替换该特定请求的外部批量请求标头值。

例如,如果您为特定嵌套请求提供了 Authorization 标头,则该标头将仅应用于指定该标头的请求。如果您为外部请求提供了 Authorization 标头,则该标头将应用于所有嵌套请求,除非这些嵌套请求将其替换为自身的 Authorization 标头。

当 Cloud Storage 收到批处理请求时,会将外部请求的查询参数和标头(如果适用)应用于各部分,然后将各部分视作单独的 HTTP 请求进行处理。

响应批处理请求

Cloud Storage 响应是一条包含 multipart/mixed 内容类型的标准 HTTP 响应。该主响应的每个部分都是对批处理请求中一项请求的响应。响应的顺序与请求相同。

与请求中的所有部分一样,每个响应部分都包含一个完整的 HTTP 响应,包括状态代码、标头和正文。此外,和请求中的各部分一样,响应中的各部分均以 Content-Type 标头为前缀,用于标记各部分的开头。如需详细了解状态代码,请参阅 Cloud Storage JSON API 的 HTTP 状态和错误代码

如果请求的某个特定部分具有 Content-ID 标头,则响应的对应部分也会有相同的 Content-ID 标头。响应的 Content-ID 标头以 response- 开头,后接请求中使用的 Content-ID 值,如示例中所示。

示例

以下批处理示例更新了 example-bucket 中三个对象的自定义元数据

批量 HTTP 请求示例

POST /batch/storage/v1 HTTP/1.1
Host: storage.googleapis.com
Content-Length: 960
Content-Type: multipart/mixed; boundary="===============7330845974216740156=="
Authorization: Bearer ya29.AHES6ZRVmB7fkLtd1XTmq6mo0S1wqZZi3-Lh_s-6Uw7p8vtgSwg

--===============7330845974216740156==
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: <b29c5de2-0db4-490b-b421-6a51b598bd22+1>

PATCH /storage/v1/b/example-bucket/o/obj1 HTTP/1.1
Content-Type: application/json
accept: application/json
content-length: 31

{"metadata": {"type": "tabby"}}
--===============7330845974216740156==
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: <b29c5de2-0db4-490b-b421-6a51b598bd22+2>

PATCH /storage/v1/b/example-bucket/o/obj2 HTTP/1.1
Content-Type: application/json
accept: application/json
content-length: 32

{"metadata": {"type": "tuxedo"}}
--===============7330845974216740156==
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: <b29c5de2-0db4-490b-b421-6a51b598bd22+3>

PATCH /storage/v1/b/example-bucket/o/obj3 HTTP/1.1
Content-Type: application/json
accept: application/json
content-length: 32

{"metadata": {"type": "calico"}}
--===============7330845974216740156==--

批量 HTTP 响应示例

此部分是对上一部分中的示例请求的响应。

HTTP/1.1 200 OK
Content-Type: multipart/mixed; boundary=batch_pK7JBAk73-E=_AA5eFwv4m2Q=
Date: Mon, 22 Jan 2018 18:56:00 GMT
Expires: Mon, 22 Jan 2018 18:56:00 GMT
Cache-Control: private, max-age=0
Content-Length: 3767

--batch_pK7JBAk73-E=_AA5eFwv4m2Q=
Content-Type: application/http
Content-ID: <response-b29c5de2-0db4-490b-b421-6a51b598bd22+1>

HTTP/1.1 200 OK
ETag: "lGaP-E0memYDumK16YuUDM_6Gf0/V43j6azD55CPRGb9b6uytDYl61Y"
Content-Type: application/json; charset=UTF-8
Date: Mon, 22 Jan 2018 18:56:00 GMT
Expires: Mon, 22 Jan 2018 18:56:00 GMT
Cache-Control: private, max-age=0
Content-Length: 846

{
 "kind": "storage#object",
 "id": "example-bucket/obj1/1495822576643790",
 .
 .
 .
 "metadata": {
  "type": "tabby"
  },
  .
  .
  .
}

--batch_pK7JBAk73-E=_AA5eFwv4m2Q=
Content-Type: application/http
Content-ID: <response-b29c5de2-0db4-490b-b421-6a51b598bd22+2>

HTTP/1.1 200 OK
ETag: "lGaP-E0memYDumK16YuUDM_6Gf0/91POdd-sxSAkJnS8Dm7wMxBSDKk"
Content-Type: application/json; charset=UTF-8
Date: Mon, 22 Jan 2018 18:56:00 GMT
Expires: Mon, 22 Jan 2018 18:56:00 GMT
Cache-Control: private, max-age=0
Content-Length: 846

{
 "kind": "storage#object",
 "id": "example-bucket/obj2/1495822576643790",
 .
 .
 .
 "metadata": {
  "type": "tuxedo"
  },
  .
  .
  .
}

--batch_pK7JBAk73-E=_AA5eFwv4m2Q=
Content-Type: application/http
Content-ID: <response-b29c5de2-0db4-490b-b421-6a51b598bd22+3>

HTTP/1.1 200 OK
ETag: "lGaP-E0memYDumK16YuUDM_6Gf0/d2Z1F1_ZVbB1dC0YKM9rX5VAgIQ"
Content-Type: application/json; charset=UTF-8
Date: Mon, 22 Jan 2018 18:56:00 GMT
Expires: Mon, 22 Jan 2018 18:56:00 GMT
Cache-Control: private, max-age=0
Content-Length: 846

{
 "kind": "storage#object",
 "id": "example-bucket/obj3/1495822576643790",
 .
 .
 .
 "metadata": {
  "type": "calico"
  },
  .
  .
  .
}

--batch_pK7JBAk73-E=_AA5eFwv4m2Q=--

如果整体请求格式设置不正确,并且 Cloud Storage 无法解析为子请求,您会收到 400 错误。否则,即使部分或全部子请求失败,Cloud Storage 也会返回 200 状态代码。

如果整体请求返回 200 状态代码,则响应会包含每个子请求的结果,包括针对各子请求的状态码,指示子请求是成功还是失败。

后续步骤

  • 如需详细了解 API 发现文档以及如何利用它们对各种 Google API 的不同版本进行 RESTful HTTP 调用,请参阅 Google API Discovery Service