В этом документе показано, как группировать вызовы API, чтобы уменьшить количество HTTP-соединений, которые должен выполнить ваш клиент.
Этот документ посвящен пакетному запросу путем отправки HTTP-запроса. Если вместо этого вы используете клиентскую библиотеку Google для выполнения пакетного запроса, см. документацию клиентской библиотеки .
Обзор
Каждое HTTP-соединение, которое создает ваш клиент, приводит к определенным затратам. API Google Mirror поддерживает пакетную обработку, что позволяет вашему клиенту помещать несколько вызовов API в один HTTP-запрос.
Примеры ситуаций, когда вы можете использовать пакетную обработку:
- Вы только начали использовать API и вам нужно загрузить много данных.
- Пользователь внес изменения в данные, пока ваше приложение находилось в автономном режиме (отключено от Интернета), поэтому вашему приложению необходимо синхронизировать свои локальные данные с сервером, отправляя множество обновлений и удалений.
В каждом случае вместо отправки каждого вызова отдельно вы можете сгруппировать их в один HTTP-запрос. Все внутренние запросы должны направляться к одному и тому же API Google.
Вы ограничены 1000 вызовами в одном пакетном запросе. Если вам необходимо сделать больше вызовов, используйте несколько пакетных запросов.
Примечание . Пакетная система API Google Mirror использует тот же синтаксис, что и система пакетной обработки OData , но семантика отличается.
Детали партии
Пакетный запрос состоит из нескольких вызовов API, объединенных в один HTTP-запрос, который можно отправить по batchPath
, указанному в документе обнаружения API . Путь по умолчанию — /batch/ api_name / api_version
. В этом разделе подробно описан синтаксис пакетной обработки; позже будет пример .
Примечание . Набор из n запросов, объединенных вместе, учитывается при расчете лимита использования как n запросов, а не как один запрос. Перед обработкой пакетный запрос разделяется на набор запросов.
Формат пакетного запроса
Пакетный запрос – это один стандартный HTTP-запрос, содержащий несколько вызовов API Google Mirror, использующий multipart/mixed
тип контента. Внутри этого основного HTTP-запроса каждая часть содержит вложенный HTTP-запрос.
Каждая часть начинается со своего собственного HTTP-заголовка Content-Type: application/http
. Он также может иметь дополнительный заголовок Content-ID
. Однако заголовки частей предназначены только для обозначения начала части; они отделены от вложенного запроса. После того как сервер разворачивает пакетный запрос на отдельные запросы, заголовки частей игнорируются.
Тело каждой части представляет собой полный HTTP-запрос со своим собственным глаголом, URL-адресом, заголовками и телом. HTTP-запрос должен содержать только часть URL-адреса, содержащую путь; полные URL-адреса не допускаются в пакетных запросах.
Заголовки HTTP для внешнего пакетного запроса, за исключением заголовков Content-
, таких как Content-Type
, применяются к каждому запросу в пакете. Если вы указываете данный заголовок HTTP как во внешнем запросе, так и в отдельном вызове, то значение заголовка отдельного вызова переопределяет значение заголовка внешнего пакетного запроса. Заголовки отдельного вызова применяются только к этому вызову.
Например, если вы предоставляете заголовок авторизации для определенного вызова, этот заголовок применяется только к этому вызову. Если вы предоставляете заголовок авторизации для внешнего запроса, то этот заголовок применяется ко всем отдельным вызовам, если только они не переопределяют его собственными заголовками авторизации.
Когда сервер получает пакетный запрос, он применяет параметры запроса и заголовки внешнего запроса (при необходимости) к каждой части, а затем обрабатывает каждую часть, как если бы это был отдельный HTTP-запрос.
Ответ на пакетный запрос
Ответ сервера представляет собой один стандартный ответ HTTP с multipart/mixed
типом контента; каждая часть является ответом на один из запросов в пакетном запросе в том же порядке, что и запросы.
Как и части запроса, каждая часть ответа содержит полный ответ HTTP, включая код состояния, заголовки и тело. И, как и частям запроса, каждой части ответа предшествует заголовок Content-Type
, который отмечает начало части.
Если данная часть запроса имела заголовок Content-ID
, то соответствующая часть ответа имеет соответствующий заголовок Content-ID
, где исходному значению предшествует строка response-
, как показано в следующем примере.
Примечание . Сервер может выполнять ваши вызовы в любом порядке. Не рассчитывайте на то, что они будут выполнены в том порядке, в котором вы их указали. Если вы хотите гарантировать, что два вызова выполняются в заданном порядке, вы не можете отправить их в одном запросе; вместо этого отправьте первое сообщение отдельно, затем дождитесь ответа на первое, прежде чем отправлять второе.
Пример
В следующем примере показано использование пакетной обработки с API Google Mirror.
Пример пакетного запроса
POST /batch HTTP/1.1 Content-Length: content_length content-type: multipart/mixed; boundary="===============7330845974216740156==" accept-encoding: gzip, deflate --===============7330845974216740156== Content-Type: application/http Content-Transfer-Encoding: binary Content-ID: TIMELINE_INSERT_USER_1 POST /mirror/v1/timeline HTTP/1.1 Content-Type: application/json authorization: Bearer user_1_token accept: application/json content-length: 24 {"text": "Hello there!"} --===============7330845974216740156== Content-Type: application/http Content-Transfer-Encoding: binary Content-ID: TIMELINE_INSERT_USER_2 POST /mirror/v1/timeline HTTP/1.1 Content-Type: application/json authorization: Bearer user_2_token accept: application/json content-length: 24 {"text": "Hello there!"} --===============7330845974216740156== Content-Type: application/http Content-Transfer-Encoding: binary Content-ID: TIMELINE_INSERT_USER_3 POST /mirror/v1/timeline HTTP/1.1 Content-Type: application/json authorization: Bearer user_3_token accept: application/json content-length: 24 {"text": "Hello there!"} --===============7330845974216740156==--
Пример пакетного ответа
Это ответ на пример запроса из предыдущего раздела.
HTTP/1.1 200 OK Content-Type: multipart/mixed; boundary=batch_pK7JBAk73-E=_AA5eFwv4m2Q= Date: Tue, 22 Jan 2013 18:56:00 GMT Expires: Tue, 22 Jan 2013 18:56:00 GMT Cache-Control: private, max-age=0 --batch_pK7JBAk73-E=_AA5eFwv4m2Q= Content-Type: application/http Content-ID: response-TIMELINE_INSERT_USER_1 HTTP/1.1 201 Created Content-Type: application/json Content-Length: 304 { "kind": "glass#timelineItem", "id": "1234567890", "selfLink": "https://www.googleapis.com/mirror/v1/timeline/1234567890", "created": "2012-09-25T23:28:43.192Z", "updated": "2012-09-25T23:28:43.192Z", "etag": "\"G5BI0RWvj-0jWdBrdWrPZV7xPKw/t25selcGS3uDEVT6FB09hAG-QQ\"", "text": "Hello there!" } --batch_pK7JBAk73-E=_AA5eFwv4m2Q= Content-Type: application/http Content-ID: response-TIMELINE_INSERT_USER_2 HTTP/1.1 201 Created Content-Type: application/json Content-Length: 304 { "kind": "glass#timelineItem", "id": "0987654321", "selfLink": "https://www.googleapis.com/mirror/v1/timeline/0987654321", "created": "2012-09-25T23:28:43.192Z", "updated": "2012-09-25T23:28:43.192Z", "etag": "\"G5BI0RWvj-0jWdBrdWrPZV7xPKw/t25selcGS3uDEVT6FB09hAG-QQ\"", "text": "Hello there!" } --batch_pK7JBAk73-E=_AA5eFwv4m2Q= Content-Type: application/http Content-ID: response-TIMELINE_INSERT_USER_3 HTTP/1.1 201 Created Content-Type: application/json Content-Length: 304 { "kind": "glass#timelineItem", "id": "5432109876", "selfLink": "https://www.googleapis.com/mirror/v1/timeline/5432109876", "created": "2012-09-25T23:28:43.192Z", "updated": "2012-09-25T23:28:43.192Z", "etag": "\"G5BI0RWvj-0jWdBrdWrPZV7xPKw/t25selcGS3uDEVT6FB09hAG-QQ\"", "text": "Hello there!" } --batch_pK7JBAk73-E=_AA5eFwv4m2Q=--