Performans ipuçları

Bu belgede, uygulamanızın performansını artırmak için kullanabileceğiniz bazı teknikler ele alınmaktadır. Bazı durumlarda, sunulan fikirleri açıklamak için diğer API'lerden veya genel API'lerden örnekler kullanılır. Ancak aynı kavramlar Google Cüzdan API'si için de geçerlidir.

gzip ile sıkıştırma

Her istek için gereken bant genişliğini azaltmanın kolay ve rahat bir yolu gzip sıkıştırma yöntemini etkinleştirmektir. Bu işlem, sıkıştırılmış sonuçları açmak için ek CPU süresi gerektirse de ağ maliyetleriyle ilgili avantajları sayesinde genellikle çok faydalıdır.

Gzip ile kodlanmış bir yanıt almak için iki işlem yapmanız gerekir: Accept-Encoding üstbilgisini ayarlamak ve kullanıcı aracınızı gzip dizesini içerecek şekilde değiştirmek. Gzip sıkıştırma yöntemini etkinleştirmek için uygun şekilde oluşturulmuş HTTP üstbilgilerine dair bir örneği aşağıda bulabilirsiniz:

Accept-Encoding: gzip
User-Agent: my program (gzip)

Kısmi kaynaklarla çalışma

API çağrılarınızın performansını artırmanın bir diğer yolu da yalnızca ilgilendiğiniz veri kısmını göndermek ve almak. Bu sayede uygulamanız gereksiz alanları aktarmak, ayrıştırmak ve depolamak zorunda kalmaz; ağ, CPU, bellek gibi kaynakları daha verimli kullanabilir.

İki tür kısmi istek vardır:

  • Kısmi yanıt: Yanıta hangi alanların dahil edileceğini belirttiğiniz istek (fields istek parametresini kullanın).
  • Yama: Yalnızca değiştirmek istediğiniz alanları gönderdiğiniz bir güncelleme isteğidir (PATCH HTTP fiilini kullanın).

Kısmi istekte bulunma hakkında daha fazla bilgiyi aşağıdaki bölümlerde bulabilirsiniz.

Kısmi yanıt

Varsayılan olarak, sunucu istekleri işledikten sonra bir kaynağın tam gösterimini geri gönderir. Daha iyi performans için sunucudan yalnızca gerçekten ihtiyacınız olan alanları göndermesini isteyebilir ve sadece kısmi yanıt alabilirsiniz.

Kısmi yanıt istemek için, döndürülmesini istediğiniz alanları belirtmek üzere fields istek parametresini kullanın Bu parametreyi, yanıt verileri döndüren tüm isteklerle kullanabilirsiniz.

fields parametresinin yalnızca yanıt verilerini etkilediğini, göndermeniz gereken verileri (varsa) etkilemediğini unutmayın. Kaynakları değiştirirken gönderdiğiniz veri miktarını azaltmak için yama isteği kullanın.

Örnek

Aşağıdaki örnekte fields parametresinin, genel (kurgusal) bir "Demo" API ile kullanımı gösterilmektedir.

Basit istek: Bu HTTP GET isteğinde fields parametresi atlanmış ve kaynağın tamamı döndürülmüştür.

https://www.googleapis.com/demo/v1

Tam kaynak yanıtı: Tam kaynak verileri, kısa olması için çıkarılan diğer birçok alanın yanı sıra aşağıdaki alanları içerir.

{
  "kind": "demo",
  ...
  "items": [
  {
    "title": "First title",
    "comment": "First comment.",
    "characteristics": {
      "length": "short",
      "accuracy": "high",
      "followers": ["Jo", "Will"],
    },
    "status": "active",
    ...
  },
  {
    "title": "Second title",
    "comment": "Second comment.",
    "characteristics": {
      "length": "long",
      "accuracy": "medium"
      "followers": [ ],
    },
    "status": "pending",
    ...
  },
  ...
  ]
}

Kısmi yanıt isteği: Aynı kaynak için yapılan aşağıdaki istekte, döndürülen veri miktarını önemli ölçüde azaltmak için fields parametresi kullanılmıştır.

https://www.googleapis.com/demo/v1?fields=kind,items(title,characteristics/length)

Kısmi yanıt: Yukarıdaki isteğe yanıt olarak sunucu, yalnızca tür bilgilerini içeren bir yanıt ve her öğede yalnızca HTML başlığı ile uzunluk özelliği bilgilerini içeren, sadeleştirilmiş bir öğe dizisi gönderir.

200 OK
{
  "kind": "demo",
  "items": [{
    "title": "First title",
    "characteristics": {
      "length": "short"
    }
  }, {
    "title": "Second title",
    "characteristics": {
      "length": "long"
    }
  },
  ...
  ]
}

Yanıtın, yalnızca seçilen alanları ve bunları barındıran üst nesneleri içeren bir JSON nesnesi olduğunu unutmayın.

fields parametresinin nasıl biçimlendirileceğiyle ilgili ayrıntılar bir sonraki bölümde, yanıtın tam olarak ne içerdiğine dair daha fazla bilgi ise ondan sonraki bölümde ele alınmaktadır.

Alanlar parametresi söz dizimi özeti

fields istek parametresi değerinin biçimi temel olarak XPath söz dizimine benzer. Desteklenen söz dizimi aşağıda özetlenmiştir. Ek örnekler ise sonraki bölümde verilmiştir.

  • Birden fazla alan seçmek için virgülle ayrılmış bir liste kullanın.
  • a alanı içine yerleştirilmiş bir b alanı seçmek için a/b öğesini, b alanı içine yerleştirilmiş c alanını seçmek için ise a/b/c öğesini kullanın.

    İstisna: Yanıtın data: { ... } gibi görünen bir data nesnesinin içine yerleştirildiği, "data" sarmalayıcılarını kullanan API yanıtları için fields spesifikasyonuna "data" öğesini eklemeyin. Veri nesnesinin data/a/b gibi bir alan spesifikasyonuyla eklenmesi hataya neden olur. Bunun yerine, a/b gibi bir fields spesifikasyonu kullanın.

  • Dizilerin veya nesnelerin belirli bir alt alan grubunu istemek için bir alt seçici kullanın. İfadeleri parantez içine yazın ("( )").

    Örneğin: fields=items(id,author/email), öğe dizisindeki her öğe için yalnızca öğe kimliğini ve yazarın e-posta adresini döndürür. Ayrıca, fields=items(id) ile fields=items/id aynı anlama gelecek şekilde tek bir alt alan da belirtebilirsiniz.

  • Gerekirse alan seçimlerinde joker karakterler kullanın.

    Örneğin: fields=items/pagemap/*, bir sayfa haritasındaki tüm nesneleri seçer.

Alanlar parametresinin kullanımıyla ilgili daha fazla örnek

Aşağıdaki örneklerde, fields parametre değerinin yanıtı nasıl etkilediğine dair açıklamalar yer almaktadır.

Not: Tüm sorgu parametresi değerlerinde olduğu gibi, fields parametre değeri de URL olarak kodlanmalıdır. Daha kolay anlaşılması için bu belgedeki örneklerde kodlama kısmı atlanmıştır.

Döndürülmesini istediğiniz alanları belirleyin veya alan seçimlerini yapın.
fields istek parametresinin değeri, virgülle ayrılmış bir alan listesidir ve her alan, yanıtın köküne göre belirtilir. Bu nedenle, list işlemi gerçekleştiriyorsanız yanıt bir koleksiyondur ve genellikle bir kaynak dizisi içerir. Tek bir kaynak döndüren bir işlem gerçekleştiriyorsanız alanlar bu kaynağa göre belirtilir. Seçtiğiniz alan bir dizi ise (veya dizinin bir parçasıysa) sunucu, dizideki tüm öğelerin seçilen kısmını döndürür.

Aşağıda, koleksiyon düzeyinde bazı örnekler verilmiştir:
Örnekler Efekt
items Öğe dizisindeki tüm öğeleri (her öğedeki tüm alanlar dahil) döndürür ancak başka alan döndürmez.
etag,items Hem etag alanını hem de öğe dizisindeki tüm öğeleri döndürür.
items/title Öğe dizisindeki tüm öğeler için yalnızca title alanını döndürür.

İç içe yerleştirilmiş bir alan döndürüldüğünde yanıt, kapsayan üst nesneleri içerir. Üst alanlar, yalnızca açıkça seçilmiş olan alt alanları içerir, seçilmeyenleri içermez.
context/facets/label facets dizisinin tüm üyeleri için yalnızca label alanını döndürür. Bu alan, context nesnesinin altında yer alır.
items/pagemap/*/title Öğe dizisindeki her öğe için, pagemap öğesinin alt öğeleri olan tüm nesnelerin yalnızca title alanı (varsa) döndürülür.

Aşağıda, kaynak düzeyinde bazı örnekler verilmiştir:
Örnekler Efekt
title İstenen kaynağın title alanını döndürür.
author/uri İstenen kaynaktaki author nesnesinin uri alt alanını döndürür.
links/*/href
links öğesinin alt öğeleri olan tüm nesnelerin href alanını döndürür.
Alt seçimleri kullanarak belirli alanların yalnızca bazı bölümlerini isteyin.
Varsayılan olarak, isteğinizde belirli alanlar belirtiliyorsa sunucu, nesneleri veya dizi öğelerini tamamen döndürür. Yalnızca belirli alt alanları içeren bir yanıt belirtebilirsiniz. Bunu, aşağıdaki örnekte gösterildiği gibi "( )" alt seçim söz dizimini kullanarak yapabilirsiniz.
Örnek Efekt
items(title,author/uri) Öğe dizisindeki her öğe için yalnızca title ve yazarın uri değerlerini döndürür.

Kısmi yanıtları işleme

Bir sunucu, fields sorgu parametresini içeren geçerli bir isteği işledikten sonra istenen verilerle birlikte bir HTTP 200 OK durum kodu gönderir. fields sorgu parametresinde bir hata varsa veya parametre herhangi bir şekilde geçersizse sunucu, HTTP 400 Bad Request durum koduyla birlikte, kullanıcıya alan seçimiyle ilgili neyin yanlış olduğunu açıklayan bir hata mesajı döndürür (ör. "Invalid field selection a/b").

Yukarıdaki giriş bölümünde gösterilen kısmi yanıt örneğini aşağıda bulabilirsiniz. Hangi alanların döndürüleceğini belirtmek için istekte fields parametresi kullanılır.

https://www.googleapis.com/demo/v1?fields=kind,items(title,characteristics/length)

Kısmi yanıt şu şekilde görünür:

200 OK
{
  "kind": "demo",
  "items": [{
    "title": "First title",
    "characteristics": {
      "length": "short"
    }
  }, {
    "title": "Second title",
    "characteristics": {
      "length": "long"
    }
  },
  ...
  ]
}

Not: Verilerin sayfalara ayrılması için sorgu parametrelerini (ör. maxResults ve nextPageToken) destekleyen API'lerde, her sorgunun sonuçlarını yönetilebilir bir boyuta indirmek için bu parametreleri kullanın. Aksi takdirde, kısmi yanıtla elde edilebilecek performans artışları gerçekleşmeyebilir.

Yama (kısmi güncelleme)

Ayrıca kaynakları değiştirirken gereksiz veriler göndermekten de kaçınabilirsiniz. Yalnızca değiştirdiğiniz belirli alanlar için güncellenen verileri göndermek üzere HTTP PATCH fiilini kullanın. Bu belgede açıklanan yama semantiği, kısmi güncellemenin eski GData uygulamasında kullanılan semantikten farklıdır (ve daha basittir).

Aşağıdaki kısa örnekte, yama kullanmanın küçük bir güncelleme yapmak için göndermeniz gereken verileri nasıl en aza indirdiği gösterilmektedir.

Örnek

Bu örnekte, yalnızca genel (kurgusal) bir "Demo" API kaynağının başlığını güncellemek için basit bir yama isteği gösterilmektedir. Kaynakta ayrıca bir yorum, bir dizi özellik, durum ve başka birçok alan da var ancak bu istek yalnızca title alanını gönderiyor. Bunun nedeni, yalnızca bu alanın değiştiriliyor olması:

PATCH https://www.googleapis.com/demo/v1/324
Authorization: Bearer your_auth_token
Content-Type: application/json

{
  "title": "New title"
}

Yanıt:

200 OK
{
  "title": "New title",
  "comment": "First comment.",
  "characteristics": {
    "length": "short",
    "accuracy": "high",
    "followers": ["Jo", "Will"],
  },
  "status": "active",
  ...
}

Sunucu, güncellenen kaynağın tam temsiliyle birlikte 200 OK durum kodunu döndürür. Yama isteğine yalnızca title alanı dahil edildiğinden, önceki değerden farklı olan tek değer budur.

Not: Kısmi yanıt fields parametresini yama ile birlikte kullanırsanız güncelleme isteklerinizin verimliliğini daha da artırabilirsiniz. Yama isteği yalnızca isteğin boyutunu küçültür. Kısmi yanıt, yanıtın boyutunu küçültür. Bu nedenle, her iki yönde de gönderilen veri miktarını azaltmak için fields parametresini içeren bir yama isteği kullanın.

Yama isteğinin anlamı

Yama isteğinin gövde bölümünde yalnızca değiştirmek istediğiniz kaynak alanları bulunur. Bir alan belirttiğinizde, kapsayan üst öğeler kısmi yanıt ile döndürüldüğü gibi, kapsayan tüm üst öğeleri de eklemeniz gerekir. Gönderdiğiniz değiştirilmiş veriler, varsa üst nesnenin verileriyle birleştirilir.

  • Ekle: Henüz mevcut olmayan bir alanı eklemek için yeni alanı ve değerini belirtin.
  • Değiştir: Mevcut bir alanın değerini değiştirmek için alanı belirtin ve yeni değere ayarlayın.
  • Silme: Bir alanı silmek için alanı belirtin ve null olarak ayarlayın. Örneğin, "comment": null. Ayrıca, değiştirilebilir bir nesneyi null olarak ayarlayarak tamamını silebilirsiniz. Java API İstemci Kitaplığı'nı kullanıyorsanız bunun yerine Data.NULL_STRING kullanın. Ayrıntılar için JSON null başlıklı makaleye bakın.

Dizilerle ilgili not: Dizi içeren yama istekleri, mevcut diziyi sizin sağladığınız diziyle değiştirir. Bir dizideki öğeleri parça parça değiştiremez, ekleyemez veya silemezsiniz.

Okuma-değiştirme-yazma döngüsünde yama kullanma

Değiştirmek istediğiniz verileri içeren kısmi bir yanıt alarak başlamak faydalı olabilir. Bu durum, özellikle kaynakları başarılı bir şekilde güncellemek için If-Match HTTP üstbilgisinde geçerli ETag değerini sağlamanız gerektiğinden ETag'leri kullanan kaynaklar için önemlidir. Verileri aldıktan sonra değiştirmek istediğiniz değerleri düzenleyebilir ve değiştirilen kısmi temsili bir yama isteğiyle geri gönderebilirsiniz. Aşağıdaki örnekte, Demo kaynağının ETag'leri kullandığı varsayılmaktadır:

GET https://www.googleapis.com/demo/v1/324?fields=etag,title,comment,characteristics
Authorization: Bearer your_auth_token

Bu, kısmi yanıttır:

200 OK
{
  "etag": "ETagString"
  "title": "New title"
  "comment": "First comment.",
  "characteristics": {
    "length": "short",
    "level": "5",
    "followers": ["Jo", "Will"],
  }
}

Aşağıdaki yama isteği bu yanıta dayanmaktadır. Aşağıda gösterildiği gibi, yama yanıtında döndürülen verileri sınırlamak için fields parametresini de kullanır:

PATCH https://www.googleapis.com/demo/v1/324?fields=etag,title,comment,characteristics
Authorization: Bearer your_auth_token
Content-Type: application/json
If-Match: "ETagString"
{
  "etag": "ETagString"
  "title": "",                  /* Clear the value of the title by setting it to the empty string. */
  "comment": null,              /* Delete the comment by replacing its value with null. */
  "characteristics": {
    "length": "short",
    "level": "10",              /* Modify the level value. */
    "followers": ["Jo", "Liz"], /* Replace the followers array to delete Will and add Liz. */
    "accuracy": "high"          /* Add a new characteristic. */
  },
}

Sunucu, 200 OK HTTP durum koduyla ve güncellenen kaynağın kısmi temsiliyle yanıt verir:

200 OK
{
  "etag": "newETagString"
  "title": "",                 /* Title is cleared; deleted comment field is missing. */
  "characteristics": {
    "length": "short",
    "level": "10",             /* Value is updated.*/
    "followers": ["Jo" "Liz"], /* New follower Liz is present; deleted Will is missing. */
    "accuracy": "high"         /* New characteristic is present. */
  }
}

Doğrudan yama isteği oluşturma

Bazı yama isteklerini daha önce aldığınız verilere göre oluşturmanız gerekir. Örneğin, bir diziye öğe eklemek ve mevcut dizi öğelerini kaybetmek istemiyorsanız önce mevcut verileri almanız gerekir. Benzer şekilde, bir API ETag'leri kullanıyorsa kaynağı başarılı bir şekilde güncellemek için isteğinizle birlikte önceki ETag değerini göndermeniz gerekir.

Not: ETag'ler kullanıldığında bir yamanın uygulanmasını zorlamak için "If-Match: *" HTTP üstbilgisini kullanabilirsiniz.  Bunu yaparsanız yazmadan önce okuma işlemini gerçekleştirmeniz gerekmez.

Ancak diğer durumlarda, mevcut verileri önce almadan yama isteğini doğrudan oluşturabilirsiniz. Örneğin, bir alanı yeni bir değerle güncelleyen veya yeni bir alan ekleyen bir yama isteğini kolayca ayarlayabilirsiniz. Örnek:

PATCH https://www.googleapis.com/demo/v1/324?fields=comment,characteristics
Authorization: Bearer your_auth_token
Content-Type: application/json

{
  "comment": "A new comment",
  "characteristics": {
    "volume": "loud",
    "accuracy": null
  }
}

Bu istekte, yorum alanında mevcut bir değer varsa yeni değer bu değeri geçersiz kılar. Aksi takdirde, yeni değer ayarlanır. Benzer şekilde, bir hacim özelliği varsa değeri üzerine yazılır, yoksa oluşturulur. Ayarlandıysa doğruluk alanı kaldırılır.

Yama yanıtını işleme

API, geçerli bir yama isteğini işledikten sonra değiştirilen kaynağın tam temsiliyle birlikte 200 OK HTTP yanıt kodunu döndürür. API tarafından ETag'ler kullanılıyorsa sunucu, bir yama isteğini başarıyla işlediğinde ETag değerlerini PUT ile yaptığı gibi günceller.

Yama isteği, döndürdüğü veri miktarını azaltmak için fields parametresini kullanmadığınız sürece kaynak temsilinin tamamını döndürür.

Bir yama isteği, söz dizimi veya anlam açısından geçersiz olan yeni bir kaynak durumuyla sonuçlanırsa sunucu 400 Bad Request veya 422 Unprocessable Entity HTTP durum kodunu döndürür ve kaynak durumu değişmeden kalır. Örneğin, zorunlu bir alanın değerini silmeye çalışırsanız sunucu hata döndürür.

PATCH HTTP fiili desteklenmediğinde alternatif gösterim

Güvenlik duvarınız HTTP PATCH isteklerine izin vermiyorsa HTTP POST isteği gönderin ve geçersiz kılma üstbilgisini aşağıdaki örnekte gösterildiği gibi PATCH olarak ayarlayın:

POST https://www.googleapis.com/...
X-HTTP-Method-Override: PATCH
...

Yama ve güncelleme arasındaki fark

Uygulamada, HTTP PUT fiilini kullanan bir güncelleme isteği için veri gönderdiğinizde yalnızca zorunlu veya isteğe bağlı olan alanları göndermeniz gerekir. Sunucu tarafından ayarlanan alanlar için değer gönderirseniz bu değerler yoksayılır. Bu, kısmi güncelleme yapmanın başka bir yolu gibi görünse de bu yaklaşımın bazı sınırlamaları vardır. HTTP PUT fiilini kullanan güncellemelerde, gerekli parametreleri sağlamazsanız istek başarısız olur ve isteğe bağlı parametreleri sağlamazsanız daha önce ayarlanan veriler temizlenir.

Bu nedenle yama kullanmak çok daha güvenlidir. Yalnızca değiştirmek istediğiniz alanlarla ilgili verileri sağlarsınız. Atladığınız alanlar temizlenmez. Bu kuralın tek istisnası, tekrarlayan öğeler veya diziler için geçerlidir: Bunların tümünü atlarsanız olduğu gibi kalırlar. Bunlardan herhangi birini sağlarsanız tüm küme, sağladığınız küme ile değiştirilir.

Google Cüzdan'a toplu istekler

Google Cüzdan API, bir istemcinin kurması gereken bağlantı sayısını azaltmak için API çağrılarını toplu hale getirmeyi destekler. Toplu istek ve yanıt yapısı hakkında daha fazla bilgi için Toplu işlem ayrıntıları başlıklı makaleyi inceleyin.

Aşağıdaki örnek kodda, isteklerin toplu olarak gönderilmesi gösterilmektedir. Java ve PHP örneklerinde, sınıf ve nesne oluşturmayı basitleştirmek için Google Cüzdan kitaplıkları kullanılır.

Java

Java'da entegrasyonunuza başlamak için GitHub'daki kod örneklerimize göz atın.

/**
 * Batch create Google Wallet objects from an existing class.
 *
 * @param issuerId The issuer ID being used for this request.
 * @param classSuffix Developer-defined unique ID for this pass class.
 */
public void batchCreateObjects(String issuerId, String classSuffix) throws IOException {
  // Create the batch request client
  BatchRequest batch = service.batch(new HttpCredentialsAdapter(credentials));

  // The callback will be invoked for each request in the batch
  JsonBatchCallback<FlightObject> callback =
      new JsonBatchCallback<FlightObject>() {
        // Invoked if the request was successful
        public void onSuccess(FlightObject response, HttpHeaders responseHeaders) {
          System.out.println("Batch insert response");
          System.out.println(response.toString());
        }

        // Invoked if the request failed
        public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {
          System.out.println("Error Message: " + e.getMessage());
        }
      };

  // Example: Generate three new pass objects
  for (int i = 0; i < 3; i++) {
    // Generate a random object suffix
    String objectSuffix = UUID.randomUUID().toString().replaceAll("[^\\w.-]", "_");

    // See link below for more information on required properties
    // https://developers.google.com/wallet/tickets/boarding-passes/rest/v1/flightobject
    FlightObject batchObject =
        new FlightObject()
            .setId(String.format("%s.%s", issuerId, objectSuffix))
            .setClassId(String.format("%s.%s", issuerId, classSuffix))
            .setState("ACTIVE")
            .setHeroImage(
                new Image()
                    .setSourceUri(
                        new ImageUri()
                            .setUri(
                                "https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg"))
                    .setContentDescription(
                        new LocalizedString()
                            .setDefaultValue(
                                new TranslatedString()
                                    .setLanguage("en-US")
                                    .setValue("Hero image description"))))
            .setTextModulesData(
                    List.of(
                            new TextModuleData()
                                    .setHeader("Text module header")
                                    .setBody("Text module body")
                                    .setId("TEXT_MODULE_ID")))
            .setLinksModuleData(
                new LinksModuleData()
                    .setUris(
                        Arrays.asList(
                            new Uri()
                                .setUri("http://maps.google.com/")
                                .setDescription("Link module URI description")
                                .setId("LINK_MODULE_URI_ID"),
                            new Uri()
                                .setUri("tel:6505555555")
                                .setDescription("Link module tel description")
                                .setId("LINK_MODULE_TEL_ID"))))
            .setImageModulesData(
                    List.of(
                            new ImageModuleData()
                                    .setMainImage(
                                            new Image()
                                                    .setSourceUri(
                                                            new ImageUri()
                                                                    .setUri(
                                                                            "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg"))
                                                    .setContentDescription(
                                                            new LocalizedString()
                                                                    .setDefaultValue(
                                                                            new TranslatedString()
                                                                                    .setLanguage("en-US")
                                                                                    .setValue("Image module description"))))
                                    .setId("IMAGE_MODULE_ID")))
            .setBarcode(new Barcode().setType("QR_CODE").setValue("QR code value"))
            .setLocations(
                    List.of(
                            new LatLongPoint()
                                    .setLatitude(37.424015499999996)
                                    .setLongitude(-122.09259560000001)))
            .setPassengerName("Passenger name")
            .setBoardingAndSeatingInfo(
                new BoardingAndSeatingInfo().setBoardingGroup("B").setSeatNumber("42"))
            .setReservationInfo(new ReservationInfo().setConfirmationCode("Confirmation code"));

    service.flightobject().insert(batchObject).queue(batch, callback);
  }

  // Invoke the batch API calls
  batch.execute();
}

PHP

PHP'de entegrasyonunuza başlamak için GitHub'daki kod örneklerimizin tamamına bakın.

/**
 * Batch create Google Wallet objects from an existing class.
 *
 * @param string $issuerId The issuer ID being used for this request.
 * @param string $classSuffix Developer-defined unique ID for the pass class.
 */
public function batchCreateObjects(string $issuerId, string $classSuffix)
{
  // Update the client to enable batch requests
  $this->client->setUseBatch(true);
  $batch = $this->service->createBatch();

  // Example: Generate three new pass objects
  for ($i = 0; $i < 3; $i++) {
    // Generate a random object suffix
    $objectSuffix = preg_replace('/[^\w.-]/i', '_', uniqid());

    // See link below for more information on required properties
    // https://developers.google.com/wallet/tickets/boarding-passes/rest/v1/flightobject
    $batchObject = new FlightObject([
      'id' => "{$issuerId}.{$objectSuffix}",
      'classId' => "{$issuerId}.{$classSuffix}",
      'state' => 'ACTIVE',
      'heroImage' => new Image([
        'sourceUri' => new ImageUri([
          'uri' => 'https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg'
        ]),
        'contentDescription' => new LocalizedString([
          'defaultValue' => new TranslatedString([
            'language' => 'en-US',
            'value' => 'Hero image description'
          ])
        ])
      ]),
      'textModulesData' => [
        new TextModuleData([
          'header' => 'Text module header',
          'body' => 'Text module body',
          'id' => 'TEXT_MODULE_ID'
        ])
      ],
      'linksModuleData' => new LinksModuleData([
        'uris' => [
          new Uri([
            'uri' => 'http://maps.google.com/',
            'description' => 'Link module URI description',
            'id' => 'LINK_MODULE_URI_ID'
          ]),
          new Uri([
            'uri' => 'tel:6505555555',
            'description' => 'Link module tel description',
            'id' => 'LINK_MODULE_TEL_ID'
          ])
        ]
      ]),
      'imageModulesData' => [
        new ImageModuleData([
          'mainImage' => new Image([
            'sourceUri' => new ImageUri([
              'uri' => 'http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg'
            ]),
            'contentDescription' => new LocalizedString([
              'defaultValue' => new TranslatedString([
                'language' => 'en-US',
                'value' => 'Image module description'
              ])
            ])
          ]),
          'id' => 'IMAGE_MODULE_ID'
        ])
      ],
      'barcode' => new Barcode([
        'type' => 'QR_CODE',
        'value' => 'QR code value'
      ]),
      'locations' => [
        new LatLongPoint([
          'latitude' => 37.424015499999996,
          'longitude' =>  -122.09259560000001
        ])
      ],
      'passengerName' => 'Passenger name',
      'boardingAndSeatingInfo' => new BoardingAndSeatingInfo([
        'boardingGroup' => 'B',
        'seatNumber' => '42'
      ]),
      'reservationInfo' => new ReservationInfo([
        'confirmationCode' => 'Confirmation code'
      ])
    ]);

    $batch->add($this->service->flightobject->insert($batchObject));
  }

  // Make the batch request
  $batchResponse = $batch->execute();

  print "Batch insert response\n";
  foreach ($batchResponse as $key => $value) {
    if ($value instanceof Google_Service_Exception) {
      print_r($value->getErrors());
      continue;
    }
    print "{$value->getId()}\n";
  }
}

Python

Python'da entegrasyonunuza başlamak için GitHub'daki kod örneklerimizin tamamına bakın.

def batch_create_objects(self, issuer_id: str, class_suffix: str):
    """Batch create Google Wallet objects from an existing class.

    The request body will be a multiline string. See below for information.

    https://cloud.google.com/compute/docs/api/how-tos/batch#example

    Args:
        issuer_id (str): The issuer ID being used for this request.
        class_suffix (str): Developer-defined unique ID for this pass class.
    """
    batch = self.client.new_batch_http_request()

    # Example: Generate three new pass objects
    for _ in range(3):
        # Generate a random object suffix
        object_suffix = str(uuid.uuid4()).replace('[^\\w.-]', '_')

        # See link below for more information on required properties
        # https://developers.google.com/wallet/tickets/boarding-passes/rest/v1/flightobject
        batch_object = {
            'id': f'{issuer_id}.{object_suffix}',
            'classId': f'{issuer_id}.{class_suffix}',
            'state': 'ACTIVE',
            'heroImage': {
                'sourceUri': {
                    'uri':
                        'https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg'
                },
                'contentDescription': {
                    'defaultValue': {
                        'language': 'en-US',
                        'value': 'Hero image description'
                    }
                }
            },
            'textModulesData': [{
                'header': 'Text module header',
                'body': 'Text module body',
                'id': 'TEXT_MODULE_ID'
            }],
            'linksModuleData': {
                'uris': [{
                    'uri': 'http://maps.google.com/',
                    'description': 'Link module URI description',
                    'id': 'LINK_MODULE_URI_ID'
                }, {
                    'uri': 'tel:6505555555',
                    'description': 'Link module tel description',
                    'id': 'LINK_MODULE_TEL_ID'
                }]
            },
            'imageModulesData': [{
                'mainImage': {
                    'sourceUri': {
                        'uri':
                            'http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg'
                    },
                    'contentDescription': {
                        'defaultValue': {
                            'language': 'en-US',
                            'value': 'Image module description'
                        }
                    }
                },
                'id': 'IMAGE_MODULE_ID'
            }],
            'barcode': {
                'type': 'QR_CODE',
                'value': 'QR code'
            },
            'locations': [{
                'latitude': 37.424015499999996,
                'longitude': -122.09259560000001
            }],
            'passengerName': 'Passenger name',
            'boardingAndSeatingInfo': {
                'boardingGroup': 'B',
                'seatNumber': '42'
            },
            'reservationInfo': {
                'confirmationCode': 'Confirmation code'
            }
        }

        batch.add(self.client.flightobject().insert(body=batch_object))

    # Invoke the batch API calls
    response = batch.execute()

    print('Batch complete')

C#

C# dilinde entegrasyonunuza başlamak için GitHub'daki kod örneklerimize göz atın.

/// <summary>
/// Batch create Google Wallet objects from an existing class.
/// </summary>
/// <param name="issuerId">The issuer ID being used for this request.</param>
/// <param name="classSuffix">Developer-defined unique ID for this pass class.</param>
public async void BatchCreateObjects(string issuerId, string classSuffix)
{
  // The request body will be a multiline string
  // See below for more information
  // https://cloud.google.com/compute/docs/api/how-tos/batch//example
  string data = "";

  HttpClient httpClient = new HttpClient();
  httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
    "Bearer",
    credentials.GetAccessTokenForRequestAsync().Result
  );

  // Example: Generate three new pass objects
  for (int i = 0; i < 3; i++)
  {
    // Generate a random object suffix
    string objectSuffix = Regex.Replace(Guid.NewGuid().ToString(), "[^\\w.-]", "_");

    // See link below for more information on required properties
    // https://developers.google.com/wallet/tickets/boarding-passes/rest/v1/flightobject
    FlightObject batchObject = new FlightObject
    {
      Id = $"{issuerId}.{objectSuffix}",
      ClassId = $"{issuerId}.{classSuffix}",
      State = "ACTIVE",
      HeroImage = new Image
      {
        SourceUri = new ImageUri
        {
          Uri = "https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg"
        },
        ContentDescription = new LocalizedString
        {
          DefaultValue = new TranslatedString
          {
            Language = "en-US",
            Value = "Hero image description"
          }
        }
      },
      TextModulesData = new List<TextModuleData>
      {
        new TextModuleData
        {
          Header = "Text module header",
          Body = "Text module body",
          Id = "TEXT_MODULE_ID"
        }
      },
      LinksModuleData = new LinksModuleData
      {
        Uris = new List<Google.Apis.Walletobjects.v1.Data.Uri>
        {
          new Google.Apis.Walletobjects.v1.Data.Uri
          {
            UriValue = "http://maps.google.com/",
            Description = "Link module URI description",
            Id = "LINK_MODULE_URI_ID"
          },
          new Google.Apis.Walletobjects.v1.Data.Uri
          {
            UriValue = "tel:6505555555",
            Description = "Link module tel description",
            Id = "LINK_MODULE_TEL_ID"
          }
        }
      },
      ImageModulesData = new List<ImageModuleData>
      {
        new ImageModuleData
        {
          MainImage = new Image
          {
            SourceUri = new ImageUri
            {
              Uri = "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg"
            },
            ContentDescription = new LocalizedString
            {
              DefaultValue = new TranslatedString
              {
                Language = "en-US",
                Value = "Image module description"
              }
            }
          },
          Id = "IMAGE_MODULE_ID"
        }
      },
      Barcode = new Barcode
      {
        Type = "QR_CODE",
        Value = "QR code"
      },
      Locations = new List<LatLongPoint>
      {
        new LatLongPoint
        {
          Latitude = 37.424015499999996,
          Longitude = -122.09259560000001
        }
      },
      PassengerName = "Passenger name",
      BoardingAndSeatingInfo = new BoardingAndSeatingInfo
      {
        BoardingGroup = "B",
        SeatNumber = "42"
      },
      ReservationInfo = new ReservationInfo
      {
        ConfirmationCode = "Confirmation code"
      }
    };

    data += "--batch_createobjectbatch\n";
    data += "Content-Type: application/json\n\n";
    data += "POST /walletobjects/v1/flightObject/\n\n";

    data += JsonConvert.SerializeObject(batchObject) + "\n\n";
  }
  data += "--batch_createobjectbatch--";

  // Invoke the batch API calls
  HttpRequestMessage batchObjectRequest = new HttpRequestMessage(
      HttpMethod.Post,
      "https://walletobjects.googleapis.com/batch");

  batchObjectRequest.Content = new StringContent(data);
  batchObjectRequest.Content.Headers.ContentType = new MediaTypeHeaderValue(
      "multipart/mixed");
  // `boundary` is the delimiter between API calls in the batch request
  batchObjectRequest.Content.Headers.ContentType.Parameters.Add(
      new NameValueHeaderValue("boundary", "batch_createobjectbatch"));

  HttpResponseMessage batchObjectResponse = httpClient.Send(
      batchObjectRequest);

  string batchObjectContent = await batchObjectResponse
      .Content
      .ReadAsStringAsync();

  Console.WriteLine("Batch insert response");
  Console.WriteLine(batchObjectContent);
}

Node.js

Node'da entegrasyonunuza başlamak için GitHub'daki kod örneklerimizin tamamına bakın.

/**
 * Batch create Google Wallet objects from an existing class.
 *
 * @param {string} issuerId The issuer ID being used for this request.
 * @param {string} classSuffix Developer-defined unique ID for this pass class.
 */
async batchCreateObjects(issuerId, classSuffix) {
  // See below for more information
  // https://cloud.google.com/compute/docs/api/how-tos/batch#example
  let data = '';
  let batchObject;
  let objectSuffix;

  // Example: Generate three new pass objects
  for (let i = 0; i < 3; i++) {
    // Generate a random object suffix
    objectSuffix = uuidv4().replace('[^\w.-]', '_');

    // See link below for more information on required properties
    // https://developers.google.com/wallet/tickets/boarding-passes/rest/v1/flightobject
    batchObject = {
      'id': `${issuerId}.${objectSuffix}`,
      'classId': `${issuerId}.${classSuffix}`,
      'state': 'ACTIVE',
      'heroImage': {
        'sourceUri': {
          'uri': 'https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg'
        },
        'contentDescription': {
          'defaultValue': {
            'language': 'en-US',
            'value': 'Hero image description'
          }
        }
      },
      'textModulesData': [
        {
          'header': 'Text module header',
          'body': 'Text module body',
          'id': 'TEXT_MODULE_ID'
        }
      ],
      'linksModuleData': {
        'uris': [
          {
            'uri': 'http://maps.google.com/',
            'description': 'Link module URI description',
            'id': 'LINK_MODULE_URI_ID'
          },
          {
            'uri': 'tel:6505555555',
            'description': 'Link module tel description',
            'id': 'LINK_MODULE_TEL_ID'
          }
        ]
      },
      'imageModulesData': [
        {
          'mainImage': {
            'sourceUri': {
              'uri': 'http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg'
            },
            'contentDescription': {
              'defaultValue': {
                'language': 'en-US',
                'value': 'Image module description'
              }
            }
          },
          'id': 'IMAGE_MODULE_ID'
        }
      ],
      'barcode': {
        'type': 'QR_CODE',
        'value': 'QR code'
      },
      'locations': [
        {
          'latitude': 37.424015499999996,
          'longitude': -122.09259560000001
        }
      ],
      'passengerName': 'Passenger name',
      'boardingAndSeatingInfo': {
        'boardingGroup': 'B',
        'seatNumber': '42'
      },
      'reservationInfo': {
        'confirmationCode': 'Confirmation code'
      }
    };

    data += '--batch_createobjectbatch\n';
    data += 'Content-Type: application/json\n\n';
    data += 'POST /walletobjects/v1/flightObject\n\n';

    data += JSON.stringify(batchObject) + '\n\n';
  }
  data += '--batch_createobjectbatch--';

  // Invoke the batch API calls
  let response = await this.client.context._options.auth.request({
    url: 'https://walletobjects.googleapis.com/batch',
    method: 'POST',
    data: data,
    headers: {
      // `boundary` is the delimiter between API calls in the batch request
      'Content-Type': 'multipart/mixed; boundary=batch_createobjectbatch'
    }
  });

  console.log('Batch insert response');
  console.log(response);
}

Go

Go'da entegrasyonunuza başlamak için GitHub'daki GitHub'daki kod örneklerimize bakın.

// Batch create Google Wallet objects from an existing class.
func (d *demoFlight) batchCreateObjects(issuerId, classSuffix string) {
	data := ""
	for i := 0; i < 3; i++ {
		objectSuffix := strings.ReplaceAll(uuid.New().String(), "-", "_")

		flightObject := new(walletobjects.FlightObject)
		flightObject.Id = fmt.Sprintf("%s.%s", issuerId, objectSuffix)
		flightObject.ClassId = fmt.Sprintf("%s.%s", issuerId, classSuffix)
		flightObject.State = "ACTIVE"
		flightObject.PassengerName = "Passenger name"
		flightObject.ReservationInfo = &walletobjects.ReservationInfo{
			ConfirmationCode: "Confirmation code",
		}

		flightJson, _ := json.Marshal(flightObject)
		batchObject := fmt.Sprintf("%s", flightJson)

		data += "--batch_createobjectbatch\n"
		data += "Content-Type: application/json\n\n"
		data += "POST /walletobjects/v1/flightObject\n\n"
		data += batchObject + "\n\n"
	}
	data += "--batch_createobjectbatch--"

	res, err := d.credentials.Client(oauth2.NoContext).Post("https://walletobjects.googleapis.com/batch", "multipart/mixed; boundary=batch_createobjectbatch", bytes.NewBuffer([]byte(data)))

	if err != nil {
		fmt.Println(err)
	} else {
		b, _ := io.ReadAll(res.Body)
		fmt.Printf("Batch insert response:\n%s\n", b)
	}
}