ส่งคําขอแบบกลุ่ม
จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน
บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ
เอกสารนี้แสดงวิธีจัดกลุ่มการเรียก API ไว้ด้วยกันเพื่อลดจำนวนการเชื่อมต่อที่ไคลเอ็นต์ต้องทำ
เอกสารนี้เกี่ยวข้องกับการส่งคำขอแบบกลุ่มโดยใช้ไลบรารีของไคลเอ็นต์ Java โดยเฉพาะ
ตัวอย่างพื้นฐานมีอยู่ใน
ไลบรารีของไคลเอ็นต์ Google API สำหรับ .NET ระบบแบบกลุ่มสำหรับ Google Play EMM API ใช้ HTTP เดียวกัน
ไวยากรณ์เป็นระบบการประมวลผลแบบกลุ่ม OData
ภาพรวม
คำขอแต่ละรายการที่ลูกค้าดำเนินการผ่าน Google Play EMM API จะทำให้เกิดค่าใช้จ่ายในการดำเนินการจำนวนหนึ่ง Google Play EMM API รองรับการทำงานแบบกลุ่ม เพื่อช่วยให้ไคลเอ็นต์ของคุณรวมการเรียก API หลายรายการไว้ในคำขอเดียวได้
ต่อไปนี้คือตัวอย่างสถานการณ์ที่คุณอาจต้องใช้การรวมกลุ่ม
- โดเมนเพิ่งลงทะเบียนใหม่และมีข้อมูลที่ต้องอัปโหลดมากมาย
- ผู้ใช้ทำการเปลี่ยนแปลงข้อมูลขณะที่แอปพลิเคชันของคุณออฟไลน์ ดังนั้นแอปพลิเคชันของคุณต้องซิงค์ข้อมูลจำนวนมากไว้ในเครื่องกับเซิร์ฟเวอร์
ในกรณีเช่นนี้ คุณอาจจัดกลุ่มการโทรเข้าด้วยกันเป็นคําขอเดียวแทนที่จะส่งการโทรแต่ละครั้งแยกกัน คุณยังสามารถจัดกลุ่มคำขอสำหรับผู้ใช้หลายคน หรือสำหรับ Google API หลายรายการก็ได้
อย่างไรก็ตาม ระบบจำกัดให้คุณโทรเข้ามาได้ไม่เกิน 1,000 ครั้งในคำขอเป็นกลุ่มเดียว หากต้องการโทรมากกว่าจำนวนนั้น ให้ใช้คำขอแบบกลุ่มหลายรายการ
รายละเอียดกลุ่ม
คำขอแบบกลุ่มประกอบด้วยการเรียก API หลายรายการรวมกันเป็นคำขอ JSON-RPC รายการเดียว ส่วนนี้จะอธิบายไวยากรณ์คำขอแบบกลุ่มโดยละเอียด พร้อมตัวอย่างในส่วนถัดไป
หมายเหตุ: ชุดคำขอ n ที่จัดกลุ่มไว้ด้วยกันจะนับรวมในขีดจำกัดการใช้งานเป็นคำขอ n ไม่ใช่คำขอเดียว ระบบจะแยกคำขอแบบกลุ่มออกเป็นชุดคำขอก่อนประมวลผล
ไลบรารีของไคลเอ็นต์ Java มีการเรียกเพื่อสร้างคำขอสำหรับการเรียก Google Play EMM API แต่ละครั้ง เช่น หากต้องการแสดงแอปทั้งหมดที่ติดตั้งในอุปกรณ์ ให้ใช้คำสั่งต่อไปนี้
AndroidEnterprise enterprise = ...;
InstallsListResponse response = enterprise.installs().list(enterpriseId, userId, deviceId)
.execute();
มีการเรียกใช้ batch()
เพิ่มเติมซึ่งจัดคิวคำขอหลายรายการได้ ดังที่แสดงที่นี่
AndroidEnterprise enterprise = ...;
BatchRequest batchRequest = enterprise.batch();
enterprise.installs().list(enterpriseId, userId, deviceId1).queue(batchRequest, callback1);
enterprise.installs().list(enterpriseId, userId, deviceId2).queue(batchRequest, callback2);
enterprise.installs().list(enterpriseId, userId, deviceId3).queue(batchRequest, callback3);
batchRequest.execute();
เมื่อมีการเรียกใช้ batchRequest.execute()
ระบบจะส่งคำขอทั้งหมดที่อยู่ในคิวไปยังเซิร์ฟเวอร์พร้อมกันเป็นอาร์เรย์ JSON เซิร์ฟเวอร์จะนำพารามิเตอร์การค้นหาและส่วนหัวของคำขอภายนอก (ตามความเหมาะสม) ไปใช้กับแต่ละส่วน จากนั้นจะปฏิบัติต่อแต่ละส่วนเสมือนเป็นคำขอ JSON แยกต่างหาก
การตอบกลับคำขอแบบกลุ่ม
เซิร์ฟเวอร์จะดำเนินการกับแต่ละคำขอที่แยกกัน และจัดกลุ่มผลลัพธ์เป็นคำตอบเดียวซึ่งประกอบด้วยอาร์เรย์เดียว ไลบรารีของไคลเอ็นต์จะแยกคำตอบนี้ออกเป็นคำตอบแต่ละรายการ และแต่ละคำตอบจะส่งไปยังฟังก์ชัน Callback ที่ส่งไปยัง queue()
Callback คืออินเทอร์เฟซที่กำหนดเมธอดสำหรับความล้มเหลวและเมธอดสู่ความสำเร็จ ตัวอย่างเช่น callback1
จะถูกนำมาใช้เป็นตัวอย่างดังต่อไปนี้
private class InstallsCallback implements JsonBatchCallback<InstallsListResponse> {
@Override
public void onSuccess(InstallsListResponse response, HttpHeaders responseHeaders) {
...
}
@Override
public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {
...
}
}
หมายเหตุ: เซิร์ฟเวอร์อาจดำเนินการเรียกคุณตามลำดับใดก็ได้ ดังนั้นอย่าอาศัยผลในการส่งคำขอตามลำดับที่ระบุไว้ในคำขอ หากต้องการแน่ใจว่ามีการเรียก 2 ครั้งตามลำดับที่ระบุ คุณไม่สามารถส่งคำขอเดียวได้ ให้ส่งคำขอแรกไปด้วยตัวเอง และรอการตอบกลับก่อนที่จะส่งรายการที่ 2
ตัวอย่างคำขอแบบกลุ่ม
ตัวอย่างต่อไปนี้แสดงวิธีแสดงรายการแอปทั้งหมดที่ติดตั้งในอุปกรณ์ของผู้ใช้ทั้งหมด การเรียกใช้ครั้งแรกจะใช้ในการรับรหัสขององค์กรและผู้ใช้ และต้องดำเนินการตามลำดับ เมื่อได้ ID อุปกรณ์ทั้งหมดที่มี enterprise.devices().list()
แล้ว เราจะส่งคำขอแบบกลุ่มเพื่อเรียกแอปพลิเคชันทั้งหมดในอุปกรณ์ของผู้ใช้ทั้งหมดพร้อมกัน
package com.google.playenterprise.example;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.batch.BatchRequest;
import com.google.api.client.googleapis.batch.json.JsonBatchCallback;
import com.google.api.client.googleapis.json.GoogleJsonError;
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.androidenterprise.AndroidEnterprise;
import com.google.api.services.androidenterprise.AndroidEnterprise.Installs;
import com.google.api.services.androidenterprise.AndroidEnterpriseScopes;
import com.google.api.services.androidenterprise.model.Device;
import com.google.api.services.androidenterprise.model.DevicesListResponse;
import com.google.api.services.androidenterprise.model.Enterprise;
import com.google.api.services.androidenterprise.model.Install;
import com.google.api.services.androidenterprise.model.InstallsListResponse;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* Lists all the apps installed on all devices of a given user.
*/
public class ListAllInstalls {
private AndroidEnterprise enterprise;
private final List<String> installList = new ArrayList<>();
public static void main(String[] argv) throws Exception {
if (argv.length != 2) {
throw new IllegalArgumentException("Usage: ListAllInstalls email jsonFilename");
} else if (!argv[0].contains("@")) {
throw new IllegalArgumentException("First parameter should be a valid email.");
}
new ListAllInstalls().run(argv[0], argv[1]);
}
private void run(String userEmail, String jsonKeyPath) throws IOException {
enterprise = createAndroidEnterprise(jsonKeyPath);
// Get the enterprise id, user id, and user devices.
String domain = userEmail.split("@")[1];
List<Enterprise> results = enterprise.enterprises().list(domain).execute().getEnterprise();
if (results.isEmpty()) {
throw new RuntimeException("No enterprise found.");
}
String enterpriseId = results.get(0).getId();
String userId = enterprise
.users()
.list(enterpriseId, userEmail)
.execute()
.getUser()
.get(0)
.getId();
List<Device> devices = getAllDevices(enterpriseId, userId);
// Batch all calls to get installs on all user devices.
gatherAllInstalls(enterpriseId, userId, devices);
for (String entry : installList) {
// Do something.
System.out.println(entry);
}
}
private List<Device> getAllDevices(String enterpriseId, String userId) throws IOException {
DevicesListResponse devices = enterprise.devices().list(enterpriseId, userId).execute();
return devices.getDevice();
}
private void gatherAllInstalls(String enterpriseId, String userId, List<Device> devices)
throws IOException {
BatchRequest batchRequest = enterprise.batch();
for (Device device : devices) {
Installs.List list = enterprise
.installs().list(enterpriseId, userId, device.getAndroidId());
// Each callback can take the specifics of the associated request in its constructor.
list.queue(batchRequest, new InstallsCallback(device.getAndroidId()));
}
// Executes all the queued requests and their callbacks, single-threaded.
batchRequest.execute();
}
private class InstallsCallback extends JsonBatchCallback<InstallsListResponse> {
private final String androidId;
InstallsCallback(String androidId) {
this.androidId = androidId;
}
@Override
public void onSuccess(InstallsListResponse response, HttpHeaders responseHeaders) {
for (Install install : response.getInstall()) {
installList.add(androidId + "," + install.getProductId());
}
}
@Override
public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {
throw new RuntimeException("Error fetching a device");
}
}
private AndroidEnterprise createAndroidEnterprise(String jsonKeyPath) throws IOException {
HttpTransport httpTransport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
InputStream is = new BufferedInputStream(new FileInputStream(jsonKeyPath));
final Credential credential = GoogleCredential.fromStream(is, httpTransport, jsonFactory)
.createScoped(AndroidEnterpriseScopes.all());
HttpRequestInitializer httpRequestInitializer = new HttpRequestInitializer() {
@Override
public void initialize(HttpRequest request) throws IOException {
credential.initialize(request);
}
};
return new AndroidEnterprise.Builder(httpTransport, jsonFactory, httpRequestInitializer)
.build();
}
}
เนื้อหาของหน้าเว็บนี้ได้รับอนุญาตภายใต้ใบอนุญาตที่ต้องระบุที่มาของครีเอทีฟคอมมอนส์ 4.0 และตัวอย่างโค้ดได้รับอนุญาตภายใต้ใบอนุญาต Apache 2.0 เว้นแต่จะระบุไว้เป็นอย่างอื่น โปรดดูรายละเอียดที่นโยบายเว็บไซต์ Google Developers Java เป็นเครื่องหมายการค้าจดทะเบียนของ Oracle และ/หรือบริษัทในเครือ
อัปเดตล่าสุด 2025-05-08 UTC
[null,null,["อัปเดตล่าสุด 2025-05-08 UTC"],[[["\u003cp\u003eBatching API calls in the Google Play EMM API reduces overhead by combining multiple calls into a single HTTP request.\u003c/p\u003e\n"],["\u003cp\u003eThis document focuses on batch requests using the Java client library, with an example demonstrating how to list all apps installed on a user's devices.\u003c/p\u003e\n"],["\u003cp\u003eBatch requests are limited to 1000 calls and count toward usage limits as individual requests.\u003c/p\u003e\n"],["\u003cp\u003eThe server may process batched calls in any order, requiring separate requests for sequential execution.\u003c/p\u003e\n"],["\u003cp\u003eResponses to batch requests are handled by callbacks defined for each individual request within the batch.\u003c/p\u003e\n"]]],[],null,["# Send Batch Requests\n\nThis document shows how to batch API calls together to reduce the number of connections your client has to make.\n\nThis document is specifically about making a batch request using the Java client library.\nA basic example is also available in the [Google API Client Library for .NET](https://developers.google.com/api-client-library/dotnet/guide/batch). The batch system for the Google Play EMM API uses the same HTTP\nsyntax as the [OData batch processing](http://www.odata.org/documentation/odata-version-3-0/batch-processing/) system.\n\nOverview\n--------\n\nEach request that your client makes via the Google Play EMM API results in a certain amount of overhead. The Google Play EMM API supports batching, to allow your client to put several API calls into a single request.\n\nHere are some examples of situations in which you might want to use batching:\n\n- A domain has just been enrolled and now has a lot of data to upload.\n- A user made changes to data while your application was offline, so your application needs to synchronize a great deal of local data with the server.\n\nIn cases such as these, instead of sending each call separately you can group them together into a single request. You can even group requests for multiple users, or for multiple Google APIs.\n\nYou are, however, limited to 1000 calls in a single batch request. If you need to make more calls than that, use multiple batch requests.\n\nBatch details\n-------------\n\nA batch request consists of multiple API calls combined into one JSON-RPC request. This section describes the batch request syntax in detail, with an [example](#example) in the section following.\n\n**Note** : A set of \u003cvar translate=\"no\"\u003en\u003c/var\u003e requests batched together counts toward your usage limit as \u003cvar translate=\"no\"\u003en\u003c/var\u003e requests, not as one request. The batch request is taken apart into a set of requests before processing.\n\n### Format of a batch request\n\nThe Java client library contains calls to create requests for each Google Play EMM API call. For instance, to list all apps installed on a device, you would use the following: \n\n```\nAndroidEnterprise enterprise = ...;\nInstallsListResponse response = enterprise.installs().list(enterpriseId, userId, deviceId)\n .execute();\n```\n\nThere is an additional `batch()` call that can queue several requests, as seen here: \n\n```\nAndroidEnterprise enterprise = ...;\nBatchRequest batchRequest = enterprise.batch();\nenterprise.installs().list(enterpriseId, userId, deviceId1).queue(batchRequest, callback1);\nenterprise.installs().list(enterpriseId, userId, deviceId2).queue(batchRequest, callback2);\nenterprise.installs().list(enterpriseId, userId, deviceId3).queue(batchRequest, callback3);\nbatchRequest.execute();\n```\nWhen `batchRequest.execute()` is called, all the queued requests are sent at once to the server as a JSON array. The server applies the outer request's query parameters and headers (as appropriate) to each part, and then treats each part as if it were a separate JSON request.\n\n\u003cbr /\u003e\n\n### Response to a batch request\n\nThe server executes each separate request, and groups the result into single response made of a single array. The client library splits this response into individual responses, and each one is sent to the callback function passed to `queue()`. The callback is an interface defining a method for failure and a method for success. For instance, `callback1` would be implemented as an instance of the following: \n\n```\nprivate class InstallsCallback implements JsonBatchCallback\u003cInstallsListResponse\u003e {\n\n @Override\n public void onSuccess(InstallsListResponse response, HttpHeaders responseHeaders) {\n ...\n }\n\n @Override\n public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {\n ...\n }\n}\n```\n\n**Note**: The server may perform your calls in any order, so don't rely on receiving results in the order specified in your request. If you want to ensure that two calls occur in a given order, you can't send them in a single request; instead, send the first request by itself, and wait for a response before sending the second.\n\nExample batch request\n---------------------\n\nThe following example shows how to list all the apps installed on all of a given user devices. The first calls are used to obtain the id of the enterprise and of the user, and accordingly must be executed sequentially. Once all the device ids have been obtained with `enterprise.devices().list()`, we can do a batch request to retrieve all of the applications on all the user's devices at once. \n\n```\npackage com.google.playenterprise.example;\n\nimport com.google.api.client.auth.oauth2.Credential;\nimport com.google.api.client.googleapis.auth.oauth2.GoogleCredential;\nimport com.google.api.client.googleapis.batch.BatchRequest;\nimport com.google.api.client.googleapis.batch.json.JsonBatchCallback;\nimport com.google.api.client.googleapis.json.GoogleJsonError;\nimport com.google.api.client.http.HttpHeaders;\nimport com.google.api.client.http.HttpRequest;\nimport com.google.api.client.http.HttpRequestInitializer;\nimport com.google.api.client.http.HttpTransport;\nimport com.google.api.client.http.javanet.NetHttpTransport;\nimport com.google.api.client.json.JsonFactory;\nimport com.google.api.client.json.jackson.JacksonFactory;\nimport com.google.api.services.androidenterprise.AndroidEnterprise;\nimport com.google.api.services.androidenterprise.AndroidEnterprise.Installs;\nimport com.google.api.services.androidenterprise.AndroidEnterpriseScopes;\nimport com.google.api.services.androidenterprise.model.Device;\nimport com.google.api.services.androidenterprise.model.DevicesListResponse;\nimport com.google.api.services.androidenterprise.model.Enterprise;\nimport com.google.api.services.androidenterprise.model.Install;\nimport com.google.api.services.androidenterprise.model.InstallsListResponse;\n\nimport java.io.BufferedInputStream;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Lists all the apps installed on all devices of a given user.\n */\npublic class ListAllInstalls {\n private AndroidEnterprise enterprise;\n private final List\u003cString\u003e installList = new ArrayList\u003c\u003e();\n\n public static void main(String[] argv) throws Exception {\n if (argv.length != 2) {\n throw new IllegalArgumentException(\"Usage: ListAllInstalls email jsonFilename\");\n } else if (!argv[0].contains(\"@\")) {\n throw new IllegalArgumentException(\"First parameter should be a valid email.\");\n }\n new ListAllInstalls().run(argv[0], argv[1]);\n }\n\n private void run(String userEmail, String jsonKeyPath) throws IOException {\n enterprise = createAndroidEnterprise(jsonKeyPath);\n\n // Get the enterprise id, user id, and user devices.\n String domain = userEmail.split(\"@\")[1];\n List\u003cEnterprise\u003e results = enterprise.enterprises().list(domain).execute().getEnterprise();\n if (results.isEmpty()) {\n throw new RuntimeException(\"No enterprise found.\");\n }\n String enterpriseId = results.get(0).getId();\n String userId = enterprise\n .users()\n .list(enterpriseId, userEmail)\n .execute()\n .getUser()\n .get(0)\n .getId();\n List\u003cDevice\u003e devices = getAllDevices(enterpriseId, userId);\n\n // Batch all calls to get installs on all user devices.\n gatherAllInstalls(enterpriseId, userId, devices);\n\n for (String entry : installList) {\n // Do something.\n System.out.println(entry);\n }\n }\n\n private List\u003cDevice\u003e getAllDevices(String enterpriseId, String userId) throws IOException {\n DevicesListResponse devices = enterprise.devices().list(enterpriseId, userId).execute();\n return devices.getDevice();\n }\n\n private void gatherAllInstalls(String enterpriseId, String userId, List\u003cDevice\u003e devices)\n throws IOException {\n BatchRequest batchRequest = enterprise.batch();\n for (Device device : devices) {\n Installs.List list = enterprise\n .installs().list(enterpriseId, userId, device.getAndroidId());\n // Each callback can take the specifics of the associated request in its constructor.\n list.queue(batchRequest, new InstallsCallback(device.getAndroidId()));\n }\n // Executes all the queued requests and their callbacks, single-threaded.\n batchRequest.execute();\n }\n\n private class InstallsCallback extends JsonBatchCallback\u003cInstallsListResponse\u003e {\n private final String androidId;\n\n InstallsCallback(String androidId) {\n this.androidId = androidId;\n }\n\n @Override\n public void onSuccess(InstallsListResponse response, HttpHeaders responseHeaders) {\n for (Install install : response.getInstall()) {\n installList.add(androidId + \",\" + install.getProductId());\n }\n }\n\n @Override\n public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {\n throw new RuntimeException(\"Error fetching a device\");\n }\n }\n\n private AndroidEnterprise createAndroidEnterprise(String jsonKeyPath) throws IOException {\n HttpTransport httpTransport = new NetHttpTransport();\n JsonFactory jsonFactory = new JacksonFactory();\n\n InputStream is = new BufferedInputStream(new FileInputStream(jsonKeyPath));\n final Credential credential = GoogleCredential.fromStream(is, httpTransport, jsonFactory)\n .createScoped(AndroidEnterpriseScopes.all());\n\n HttpRequestInitializer httpRequestInitializer = new HttpRequestInitializer() {\n @Override\n public void initialize(HttpRequest request) throws IOException {\n credential.initialize(request);\n }\n };\n return new AndroidEnterprise.Builder(httpTransport, jsonFactory, httpRequestInitializer)\n .build();\n }\n}\n```"]]