Toplu İstek Gönderme

Bu dokümanda, müşterinizin kurması gereken bağlantı sayısını azaltmak için API çağrılarını nasıl toplu olarak toplu olarak gösterebileceğiniz gösterilmektedir.

Bu belge özellikle Java istemci kitaplığını kullanarak toplu istek yapmayla ilgilidir. .NET için Google API İstemci Kitaplığı'nda da temel bir örnek mevcuttur. Google Play EMM API'nin toplu sistemi, OData toplu işleme sistemiyle aynı HTTP söz dizimini kullanır.

Genel bakış

İstemcinizin Google Play EMM API aracılığıyla yaptığı her istek, belirli bir ek yük ile sonuçlanır. Google Play EMM API, istemcinizin tek bir isteğe birkaç API çağrısı yapmasını sağlamak için toplu işlemleri destekler.

Aşağıda, toplu işleme özelliğini kullanmak isteyebileceğiniz durumlara ilişkin bazı örnekler verilmiştir:

  • Yeni kaydettirilen bir alana şu anda yüklenecek çok fazla veri var.
  • Bir kullanıcı, uygulamanız çevrimdışıyken verilerde değişiklik yaptı. Bu nedenle, uygulamanızın çok sayıda yerel veriyi sunucuyla senkronize etmesi gerekiyor.

Bu gibi durumlarda, her aramayı ayrı ayrı göndermek yerine tek bir istek altında gruplandırabilirsiniz. Ayrıca, birden çok kullanıcı veya birden fazla Google API'si için istekleri gruplandırabilirsiniz.

Ancak tek bir toplu istekte 1.000 aramayla sınırlısınız. Bundan daha fazla çağrı yapmanız gerekiyorsa birden çok toplu istek kullanın.

Toplu işlem ayrıntıları

Bir toplu istek, tek bir JSON-TB isteği halinde birleştirilmiş birden fazla API çağrısından oluşur. Bu bölümde toplu istek söz dizimi ayrıntılı bir şekilde açıklanmıştır. Aşağıdaki bölümde bir örnek verilmiştir.

Not: Bir araya getirilmiş n istek grubu, tek bir istek olarak değil, n istek olarak kullanım sınırınızda hesaba katılır. Toplu istek, işlenmeden önce bir dizi istek içine ayrılır.

Toplu istek biçimi

Java istemci kitaplığı, her Google Play EMM API çağrısı için istek oluşturmaya yönelik çağrılar içerir. Örneğin, bir cihazda yüklü tüm uygulamaları listelemek için aşağıdakileri kullanırsınız:

AndroidEnterprise enterprise = ...;
InstallsListResponse response = enterprise.installs().list(enterpriseId, userId, deviceId)
  .execute();

Burada görüldüğü gibi, birden fazla isteği sıraya alabilen ek bir batch() çağrısı var:

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() çağrıldığında, sıraya alınan tüm istekler sunucuya tek seferde bir JSON dizisi olarak gönderilir. Sunucu, dış isteğin sorgu parametrelerini ve başlıklarını (uygun olduğu şekilde) uygular ve ardından her bölüme ayrı bir JSON isteğiymiş gibi davranır.

Toplu isteğe yanıt

Sunucu her bir isteği yürütür ve sonucu tek bir diziden oluşturulan tek bir yanıtta gruplandırır. İstemci kitaplığı bu yanıtı ayrı yanıtlara böler ve her bir yanıt, queue() işlevine iletilen geri çağırma işlevine gönderilir. Geri çağırma, hata ve başarılı yöntem tanımlayan bir arayüzdür. Örneğin, callback1 aşağıdakilerin bir örneği olarak uygulanır:

private class InstallsCallback implements JsonBatchCallback<InstallsListResponse> {

  @Override
  public void onSuccess(InstallsListResponse response, HttpHeaders responseHeaders) {
    ...
  }

  @Override
  public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {
    ...
  }
}

Not: Sunucu, çağrılarınızı herhangi bir sırada gerçekleştirebilir. Bu nedenle, sonuçları isteğinizde belirtilen sırada almanız gerekmez. Belirli bir sırayla iki çağrının gerçekleşmesini sağlamak için bunları tek bir istekte gönderemezsiniz; bunun yerine, ilk isteği tek başına gönderin ve ikincisini göndermeden önce yanıt bekleyin.

Örnek toplu istek

Aşağıdaki örnekte, belirli bir kullanıcı cihazlarının tümünde yüklenen tüm uygulamaların nasıl listeleneceği gösterilmektedir. İlk çağrılar, kuruluşun ve kullanıcının kimliğini elde etmek için kullanılır ve buna göre sırayla yürütülmelidir. enterprise.devices().list() ile tüm cihaz kimlikleri alındıktan sonra, kullanıcının cihazındaki tüm uygulamaları tek seferde almak için toplu istek yapabiliriz.

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();
  }
}