Yêu cầu theo lô

Tài liệu này trình bày cách phân nhóm các lệnh gọi API với nhau để giảm số lượng kết nối HTTP mà khách hàng của bạn phải thực hiện.

Tài liệu này trình bày cụ thể về việc thực hiện một yêu cầu hàng loạt bằng cách gửi Yêu cầu HTTP. Thay vào đó, nếu bạn đang sử dụng thư viện ứng dụng của Google để thực hiện yêu cầu hàng loạt, hãy xem tài liệu của thư viện ứng dụng.

Tổng quan

Mỗi kết nối HTTP mà ứng dụng của bạn tạo ra sẽ dẫn đến một mức hao tổn nhất định. Màn hình và Video 360 API hỗ trợ tính năng phân lô để cho phép ứng dụng của bạn đặt nhiều lệnh gọi API vào một yêu cầu HTTP duy nhất.

Ví dụ về những trường hợp mà bạn có thể cần sử dụng tính năng phân lô:

  • Truy xuất tài nguyên từ nhiều nhà quảng cáo.
  • Tạo hoặc cập nhật hàng loạt tài nguyên.
  • Chỉnh sửa tiêu chí nhắm mục tiêu trên nhiều mục hàng.

Trong mỗi trường hợp, thay vì gửi riêng từng lệnh gọi, bạn có thể nhóm các lệnh gọi đó lại với nhau thành một yêu cầu HTTP duy nhất. Tất cả yêu cầu nội bộ phải đến cùng một API Google.

Bạn chỉ được có tối đa 1.000 lệnh gọi trong một yêu cầu hàng loạt. Nếu bạn phải thực hiện nhiều lệnh gọi hơn số lượng đó, hãy sử dụng nhiều yêu cầu theo lô.

Lưu ý: Hệ thống lô cho Display &Video Video 360 API sử dụng cú pháp giống như hệ thống xử lý theo lô OData, nhưng ngữ nghĩa thì khác.

Chi tiết gói

Yêu cầu hàng loạt bao gồm nhiều lệnh gọi API kết hợp lại thành một yêu cầu HTTP. Yêu cầu này có thể được gửi đến batchPath được chỉ định trong tài liệu về khám phá API. Đường dẫn mặc định là /batch/api_name/api_version. Phần này mô tả chi tiết cú pháp lô; sau này sẽ có ví dụ.

Lưu ý: Một tập hợp n yêu cầu được nhóm cùng nhau sẽ được tính vào hạn mức sử dụng của bạn dưới dạng n yêu cầu chứ không phải một yêu cầu. Yêu cầu hàng loạt được tách thành một nhóm yêu cầu trước khi xử lý.

Định dạng của một yêu cầu hàng loạt

Yêu cầu hàng loạt là một yêu cầu HTTP chuẩn duy nhất chứa nhiều chiến dịch Hiển thị và Lệnh gọi API Video 360, sử dụng loại nội dung multipart/mixed. Trong yêu cầu HTTP chính đó, mỗi phần đều chứa một yêu cầu HTTP lồng nhau.

Mỗi phần bắt đầu bằng tiêu đề HTTP Content-Type: application/http riêng. Tệp này cũng có thể có một tiêu đề Content-ID không bắt buộc. Tuy nhiên, các tiêu đề phần chỉ ở đó để đánh dấu phần đầu của phần này; chúng sẽ tách biệt với yêu cầu lồng nhau. Sau khi máy chủ khám phá yêu cầu theo lô thành các yêu cầu riêng biệt, tiêu đề của từng phần sẽ bị bỏ qua.

Phần nội dung của mỗi phần là một yêu cầu HTTP hoàn chỉnh, với động từ, URL, tiêu đề và nội dung riêng. Yêu cầu HTTP chỉ được chứa phần đường dẫn của URL; URL đầy đủ không được phép trong các yêu cầu hàng loạt.

Tiêu đề HTTP cho yêu cầu hàng loạt bên ngoài, ngoại trừ các tiêu đề Content- như Content-Type, áp dụng cho mọi yêu cầu trong lô. Nếu bạn chỉ định một tiêu đề HTTP nhất định trong cả yêu cầu bên ngoài và lệnh gọi riêng lẻ, thì giá trị của tiêu đề lệnh gọi riêng lẻ sẽ ghi đè giá trị của tiêu đề của yêu cầu hàng loạt bên ngoài. Tiêu đề cho từng cuộc gọi chỉ áp dụng cho cuộc gọi đó.

Ví dụ: nếu bạn cung cấp tiêu đề Uỷ quyền cho một lệnh gọi cụ thể thì tiêu đề đó chỉ áp dụng cho lệnh gọi đó. Nếu bạn cung cấp tiêu đề Uỷ quyền cho yêu cầu bên ngoài thì tiêu đề đó sẽ áp dụng cho tất cả các lệnh gọi riêng lẻ trừ phi chúng ghi đè tiêu đề Uỷ quyền bằng tiêu đề Uỷ quyền của chính họ.

Khi máy chủ nhận được yêu cầu theo lô, máy chủ sẽ áp dụng các tiêu đề và tham số truy vấn của yêu cầu bên ngoài (nếu phù hợp) cho từng phần, sau đó xử lý từng phần như thể đó là một yêu cầu HTTP riêng biệt.

Phản hồi yêu cầu hàng loạt

Phản hồi của máy chủ là phản hồi HTTP tiêu chuẩn duy nhất có loại nội dung multipart/mixed; mỗi phần là phản hồi cho một trong các yêu cầu trong yêu cầu theo lô, theo cùng thứ tự như các yêu cầu.

Giống như các phần trong yêu cầu, mỗi phần phản hồi chứa phản hồi HTTP hoàn chỉnh, bao gồm mã trạng thái, tiêu đề và nội dung. Và cũng giống như các phần trong yêu cầu, mỗi phần phản hồi đều được đứng sau một tiêu đề Content-Type đánh dấu điểm bắt đầu của phần đó.

Nếu một phần nhất định của yêu cầu có tiêu đề Content-ID, thì phần tương ứng của phản hồi cũng có tiêu đề Content-ID phù hợp, trong đó giá trị ban đầu đứng trước chuỗi response-, như trong ví dụ sau.

Lưu ý: Máy chủ có thể thực hiện các lệnh gọi của bạn theo thứ tự bất kỳ. Không tính đến việc các mô-đun này sẽ được thực thi theo thứ tự mà bạn đã chỉ định. Nếu muốn đảm bảo rằng 2 lệnh gọi xảy ra theo một thứ tự nhất định, bạn không thể gửi các lệnh gọi đó trong một yêu cầu duy nhất; thay vào đó, hãy tự gửi tin nhắn đầu tiên, sau đó đợi phản hồi cho tin nhắn đầu tiên rồi mới gửi tin nhắn thứ hai.

Ví dụ:

Ví dụ sau đây minh hoạ việc sử dụng tính năng phân lô bằng thẻ Hiển thị và API Video 360.

Ví dụ về yêu cầu hàng loạt

POST /batch HTTP/1.1
Host: displayvideo.googleapis.com
Authorization: Bearer your_auth_code
Content-Type: multipart/mixed; boundary=batch_foobarbaz
Content-Length: total_content_length

--batch_foobarbaz
Content-Type: application/http
Content-Transfer-Encoding: binary
MIME-Version: 1.0
Content-ID: <item1:12930812@displayvideo.example.com>

PATCH /v1/advertisers/advertiser_id?updateMask=displayName&fields=advertiserId,displayName HTTP/1.1
Content-Type: application/json; charset=UTF-8
Authorization: Bearer your_auth_code

{
  "displayName": "Updated Advertiser Name"
}
--batch_foobarbaz
Content-Type: application/http
Content-Transfer-Encoding: binary
MIME-Version: 1.0
Content-ID: <item2:12930812@displayvideo.example.com>

PATCH /v1/advertisers/advertiser_id/lineItems/line_item_id?updateMask=displayName&fields=lineItemId,displayName HTTP/1.1
Content-Type: application/json; charset=UTF-8
Authorization: Bearer your_auth_code

{
  "displayName": "Updated Line Item Name"
}

--batch_foobarbaz--

Ví dụ về phản hồi hàng loạt

Đây là phản hồi cho yêu cầu mẫu trong phần trước.

HTTP/1.1 200
Content-Length: response_total_content_length
Content-Type: multipart/mixed; boundary=batch_foobarbaz

--batch_foobarbaz
Content-Type: application/http
Content-ID: <response-item1:12930812@displayvideo.example.com>

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: response_part_1_content_length

{
  "advertiserId": advertiser_id,
  "displayName": "Updated Advertiser Name"
}

--batch_foobarbaz
Content-Type: application/http
Content-ID: <response-item2:12930812@displayvideo.example.com>

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: response_part_2_content_length

{
  "lineItemId": line_item_id,
  "displayName": "Updated Line Item Name"
}

--batch_foobarbaz--

Sử dụng thư viện ứng dụng

Các mã mẫu sau đây minh hoạ cách thực hiện yêu cầu hàng loạt bằng cách sử dụng Thư viện ứng dụng API của Google. Hãy xem hướng dẫn bắt đầu nhanh tương ứng để biết thêm thông tin về cách cài đặt và thiết lập thư viện.

Java

Long advertiserId = advertiser-id;
List<Long> lineItemIds = Arrays.asList(line-item-id-1, line-item-id-2);

BatchRequest batch = service.batch();
JsonBatchCallback<LineItem> callback = new JsonBatchCallback<LineItem>() {
  public void onSuccess(LineItem lineItem, HttpHeaders responseHeaders) {
    System.out.printf("Line Item '%s' is now active.\n",
        lineItem.getName());
  }

  public void onFailure (GoogleJsonError error, HttpHeaders responseHeaders)
      throws IOException{
    System.out.printf("Error activating line item: %s\n", error.getMessage());
  }
};

LineItem activatedLineItem = new LineItem().setEntityStatus("ENTITY_STATUS_ACTIVE");

for (Long lineItemId: lineItemIds) {
  service.advertisers().lineItems().patch(advertiserId, lineItemId, activatedLineItem)
      .setUpdateMask("entityStatus").queue(batch, callback);
}
batch.execute();

Python

advertiser_id = advertiser-id
line_item_ids = [line-item-id-1, line-item-id-2]

def callback(request_id, response, exception):
    if exception is not None:
        print('Error activating line item "%s": %s' %
              request_id, exception)
    else:
        print('Line item "%s" is now active.' %
              response.get('name'))

batch = service.new_batch_http_request(callback=callback)

line_item_obj = {
    'entityStatus': 'ENTITY_STATUS_ACTIVE'
}

for line_item_id in line_item_ids:
    request = service.advertisers().lineItems().patch(
        advertiserId=advertiser_id,
        lineItemId=line_item_id,
        updateMask="entityStatus",
        body=line_item_obj
    )
    batch.add(request, request_id=line_item_id)

batch.execute()

PHP

$advertiserId = advertiser-id;
$lineItemIds = array(line-item-id-1, line-item-id-2);

// Enable batching on client and create current batch
$service->getClient()->setUseBatch(true);
$batch = $service->createBatch();

// Create line item with updated fields
$updatedLineItem = new Google_Service_DisplayVideo_LineItem();
$updatedLineItem->setEntityStatus('ENTITY_STATUS_ACTIVE');

// Create request parameter array with update mask
$optParams = array('updateMask' => 'entityStatus');

// Add each patch request to the batch
foreach($lineItemIds as $lineItemId) {
    $request = $this->service->advertisers_lineItems->patch(
        $advertiserId,
        $lineItemId,
        $updatedLineItem,
        $optParams
    );
    $requestId = $lineItemId;
    $batch->add($request, $requestId);
}

// Execute batch request
$results = $batch->execute();

// Iterate through results
foreach($results as $responseId => $lineItem) {
    $lineItemId = substr($responseId, strlen('response-') + 1);
    if ($lineItem instanceof Google_Service_Exception) {
        $e = $lineItem;
        printf(
            "Error activating line item '%s': %s\n",
            $lineItemId,
            $e->getMessage()
        );
    } else {
        printf("Line item '%s' is now active.\n", $lineItem->getName());
    }
}
$service->getClient()->setUseBatch(false);