Performans ipuçları

Bu dokümanda, uygulamanızın performansını iyileştirmek için kullanabileceğiniz bazı teknikler açıklanmaktadır. Bazı durumlarda, sunulan fikirleri örneklendirmek 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 kullanarak sıkıştırma

Her istek için gereken bant genişliğini azaltmanın kolay ve kullanışlı bir yolu, gzip sıkıştırmasını etkinleştirmektir. Bu, sonuçların sıkıştırmasını açmak için ek CPU süresi gerektirse de ağ maliyetleriyle başa çıkmak genellikle çok zaman alır.

gzip kodlu bir yanıt almak için iki şey yapmanız gerekir: Accept-Encoding üstbilgisi ayarlayın ve kullanıcı aracınızı gzip dizesini içerecek şekilde değiştirin. gzip sıkıştırmasını etkinleştirmek için düzgün şekilde oluşturulmuş bir HTTP üstbilgileri örneğini burada bulabilirsiniz:

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

Kısmi kaynaklarla çalışma

API çağrılarınızın performansını iyileştirmenin diğer bir yolu, verilerin yalnızca ilgilendiğiniz bölümünü göndermek ve almaktır. Bu sayede uygulamanız gereksiz alanları aktarmak, ayrıştırmak ve depolamaktan kaçınarak ağ, CPU ve bellek gibi kaynakları daha verimli bir şekilde kullanabilir.

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

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

Kısmi talepte bulunmayla ilgili daha ayrıntılı bilgi aşağıdaki bölümlerde verilmiştir.

Kısmi yanıt

Varsayılan olarak sunucu, istekleri işlendikten sonra kaynağın tam temsilini geri gönderir. Daha iyi performans için sunucudan yalnızca gerçekten ihtiyaç duyduğunuz alanları göndermesini isteyebilir ve bunun yerine kısmi bir yanıt alabilirsiniz.

Kısmi bir yanıt istemek için fields istek parametresini kullanarak döndürülmesini istediğiniz alanları belirtin. Bu parametreyi, yanıt verileri döndüren herhangi bir istekle kullanabilirsiniz.

fields parametresinin yalnızca yanıt verilerini etkilediğini unutmayın; göndermeniz gereken verileri (varsa) etkilemez. 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 (kurmaca) "Demo" ile kullanımı gösterilmektedir API'ye gidin.

Basit istek: Bu HTTP GET isteği, fields parametresini atlar ve tam kaynağı döndürür.

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

Tam kaynak yanıtı: Tam kaynak verileri, aşağıdaki alanların yanı sıra kısaltılması için atlanan diğer 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 gönderilen aşağıdaki istek, döndürülen veri miktarını önemli ölçüde azaltmak amacıyla fields parametresini kullanı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 ve her öğede sadece HTML başlığı ile uzunluk karakteristik bilgilerini içeren sadeleştirilmiş bir öğe dizisi içeren bir yanıt 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ı kapsayan üst nesnelerini içeren bir JSON nesnesi olduğunu unutmayın.

Bir sonraki bölümde, fields parametresinin nasıl biçimlendirileceğiyle ilgili ayrıntılar ve yanıtta tam olarak neyin döndürüleceği hakkında ayrıntılı bilgi verilmiştir.

Alan parametresi söz dizimi özeti

fields istek parametresi değerinin biçimi genel olarak XPath söz dizimine bağlıdır. Desteklenen söz dizimi aşağıda özetlenmiştir ve daha fazla örnek aşağıda verilmiştir.

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

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

  • İfadeleri parantez içine yerleştirerek dizi veya nesnelerin belirli bir alt alanını istemek için bir alt seçici kullanın "( )".

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

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

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

Domains parametresini kullanmayla ilgili diğer örnekler

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 kodlamalı olmalıdır. Okunabilirliği artırmak için bu belgedeki örneklerde kodlamaya yer verilmemiştir.

Döndürülmesini istediğiniz alanları belirleyin veya alan seçimleri yapın.
fields istek parametresi değeri, alanların virgülle ayrılmış bir listesidir ve her alan, yanıtın köküne göre belirtilir. Bu nedenle, bir list işlemi gerçekleştiriyorsanız yanıt bir koleksiyon olur ve genellikle bir dizi kaynak 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 diziyse (veya dizinin parçasıysa) sunucu, dizideki tüm öğelerin seçilen bölümünü döndürür.
.
. Koleksiyon düzeyinden bazı örnekler:
Örnekler Etki
items Her bir öğedeki tüm alanlar dahil olmak üzere items dizisindeki tüm öğeleri döndürür, ancak diğer alanları döndürmez.
etag,items Hem etag alanını hem de items dizisindeki tüm öğeleri döndürür.
items/title items 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 kendilerini çevreleyen üst nesneleri içerir. Üst alanlar, açıkça seçilmediği sürece başka hiçbir alt alanı içermez.
context/facets/label context nesnesinin altında bulunan facets dizisinin tüm üyeleri için yalnızca label alanını döndürür.
items/pagemap/*/title items dizisindeki her bir öğe için yalnızca pagemap öğesinin alt öğesi olan tüm nesnelerin title alanını (varsa) döndürür.

. Kaynak düzeyinden bazı örnekler:
Örnekler Etki
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 yalnızca belirli alanların belirli kısımlarını isteyin.
Varsayılan olarak, isteğinizde belirli alanlar belirtilmişse sunucu, nesneleri veya dizi öğelerini olduğu gibi döndürür. Yalnızca belirli alt alanları içeren bir yanıt belirtebilirsiniz. Bu işlemi "( )" kullanarak yaparsınız alt seçim söz dizimini kullanabilirsiniz.
Örnek Etki
items(title,author/uri) items dizisindeki her bir öğ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 hata varsa veya başka bir şekilde geçersizse sunucu, kullanıcıya alan seçimiyle ilgili sorunun ne olduğunu bildiren bir hata mesajıyla birlikte HTTP 400 Bad Request durum kodu döndürür (örneğin, "Invalid field selection a/b").

Yukarıdaki giriş bölümünde gösterilen kısmi yanıt örneğini burada bulabilirsiniz. İstek, hangi alanların döndürüleceğini belirtmek için fields parametresini kullanır.

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

Kısmi yanıt aşağıdaki gibi görünür:

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

Not: Verileri sayfalara ayırma sorgu parametrelerini destekleyen API'lerde (örneğin, maxResults ve nextPageToken) her sorgunun sonuçlarını yönetilebilir bir boyuta küçültmek için bu parametreleri kullanın. Aksi takdirde, kısmi yanıtta elde edilecek performans artışı gerçekleşmeyebilir.

Yama (kısmi güncelleme)

Ayrıca kaynakları değiştirirken gereksiz verilerin gönderilmesini önleyebilirsiniz. Yalnızca değiştirdiğiniz belirli alanlar için güncellenmiş verileri göndermek istiyorsanız HTTP PATCH fiilini kullanın. Bu dokümanda açıklanan yama anlamları, eski kısmi güncelleme GData uygulaması olan GData uygulamasından farklı (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 (kurmaca) bir "Demo"nun başlığının güncellenmesi için basit bir yama isteği gösterilmektedir API kaynağı. Kaynakta bir yorum, bir dizi özellik, durum ve daha birçok alan da bulunur ancak bu istek, değiştirilen tek alan olduğu için yalnızca title alanını gönderir:

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 bir 200 OK durum kodu döndürür. Yama isteğine yalnızca title alanı dahil edildiğinden öncekinden 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 gönderilen veri miktarını azaltmak için fields parametresiyle bir yama isteği kullanın.

Yama isteğinin anlamı

Yama isteğinin gövdesinde yalnızca değiştirmek istediğiniz kaynak alanları bulunur. Bir alan belirttiğinizde, kapsayan üst öğelerin kısmi bir yanıtla döndürülmesi gibi, onu kapsayan üst nesneleri de eklemeniz gerekir. Gönderdiğiniz değiştirilmiş veriler, varsa üst nesnenin verileriyle birleştirilir.

  • Ekle: 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.
  • Sil: Bir alanı silmek için alanı belirtip null olarak ayarlayın. Örneğin, "comment": null. Ayrıca, bir nesneyi null değerine ayarlayarak tüm nesneyi (değişebilirse) silebilirsiniz. Java API İstemci Kitaplığı yerine Data.NULL_STRING kullanın; şunun için: ayrıntıları için JSON null sayfasına bakın.

Diziler hakkında not: Dizi içeren yama istekleri, mevcut diziyi sağladığınız diziyle değiştirir. Bir dizideki öğeleri parçalı olarak değiştiremez, ekleyemez veya silemezsiniz.

Yamayı oku-değiştir-yazma döngüsünde kullanma

Değiştirmek istediğiniz verileri içeren kısmi bir yanıt alarak başlamak yararlı bir uygulama olabilir. Bu, özellikle ETag kullanan kaynaklar için önemlidir. Çünkü kaynağı başarıyla güncellemek için If-Match HTTP başlığında geçerli ETag değerini sağlamanız gerekir. Verileri aldıktan sonra, değiştirmek istediğiniz değerleri değiştirebilir ve değiştirilmiş kısmi gösterimi bir yama isteğiyle geri gönderebilirsiniz. Aşağıda, demo kaynağının ETag kullandığını varsayan bir örnek verilmiştir:

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 göredir. Aşağıda gösterildiği gibi, yama yanıtında döndürülen verileri sınırlandırmak 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 gösterimiyle 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 istekleri için bunları daha önce aldığınız verileri temel almanız gerekir. Örneğin, bir diziye öğe eklemek istiyor ve mevcut dizi öğelerinden hiçbirini kaybetmemek istemiyorsanız önce mevcut verileri almanız gerekir. Benzer şekilde, 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ılırken bir yamanın uygulanmasını zorunlu kılmak için "If-Match: *" HTTP üst bilgisi kullanabilirsiniz. Bunu yaparsanız okuma işlemini yazmadan önce gerçekleştirmeniz gerekmez.

Ancak diğer durumlarda, yama isteğini önce mevcut verileri almadan doğrudan oluşturabilirsiniz. Örneğin, bir alanı yeni bir değerle güncelleyen veya yeni bir alan ekleyen yama isteğini kolayca oluşturabilirsiniz. Ö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 istekle birlikte, yorum alanında mevcut bir değer varsa yeni değer bu değerin üzerine yazılır. Aksi takdirde yeni değere ayarlanır. Benzer şekilde, hacim özelliği varsa değerinin üzerine yazılır. veri oluşturulmadıysa dosya oluşturulur. Doğruluk alanı (ayarlanmışsa) kaldırılır.

Yamaya verilen yanıtı işleme

API, geçerli bir yama isteğini işledikten sonra, değiştirilen kaynağın tam temsiliyle birlikte bir 200 OK HTTP yanıt kodu döndürür. API tarafından ETag'ler kullanılıyorsa sunucu, PUT ürününde olduğu gibi bir yama isteğini başarıyla işlediğinde ETag değerlerini 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 dizimsel veya semantik olarak geçersiz olan yeni bir kaynak durumuyla sonuçlanırsa sunucu, 400 Bad Request veya 422 Unprocessable Entity HTTP durum kodu döndürür ve kaynak durumu değişmez. Örneğin, zorunlu bir alanın değerini silmeye çalışırsanız sunucu bir hata döndürür.

YAMA HTTP fiili desteklenmediğinde alternatif gösterim

Güvenlik duvarınız HTTP PATCH isteklerine izin vermiyorsa bir HTTP POST isteği yapın ve geçersiz kılma başlığını aşağıda 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

Pratikte, HTTP PUT fiilini kullanan bir güncelleme isteği için veri gönderdiğinizde yalnızca zorunlu veya isteğe bağlı 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ı parametreler sağlamazsanız daha önce ayarlanmış verileri siler.

Bu nedenle yama kullanmak çok daha güvenlidir. Yalnızca değiştirmek istediğiniz alanlara veri sağlarsınız; çıkardığınız alanlar temizlenmez. Bu kuralın tek istisnası, yinelenen öğeler veya dizilerde ortaya çıkar: Tümünü atlarsanız oldukları gibi kalırlar; Herhangi birini sağlarsanız tüm grup, sağladığınız grupla değiştirilir.

Google Cüzdan'a toplu istek gönderme

Google Cüzdan API'si, API çağrılarının toplu olarak gönderilmesini desteklediğinden birçok bağlantı var. Toplu istek ve bununla ilgili daha fazla bilgi için Toplu ayrıntılar bölümüne göz atın.

Aşağıdaki örnek kod toplu işlem isteklerini göstermektedir. Java ve PHP örnek olarak Google Cüzdan'ı kitaplıklarını kullanarak sınıf ve nesne oluşturmayı kolaylaştırır.

Java

Java entegrasyonunuzu başlatmak için kod örneklerini inceleyin.

/**
 * 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<TransitObject> callback =
      new JsonBatchCallback<TransitObject>() {
        // Invoked if the request was successful
        public void onSuccess(TransitObject 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/transit-passes/qr-code/rest/v1/transitobject
    TransitObject batchObject =
        new TransitObject()
            .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)))
            .setPassengerType("SINGLE_PASSENGER")
            .setPassengerNames("Passenger names")
            .setTripType("ONE_WAY")
            .setTicketLeg(
                new TicketLeg()
                    .setOriginStationCode("LA")
                    .setOriginName(
                        new LocalizedString()
                            .setDefaultValue(
                                new TranslatedString()
                                    .setLanguage("en-US")
                                    .setValue("Origin name")))
                    .setDestinationStationCode("SFO")
                    .setDestinationName(
                        new LocalizedString()
                            .setDefaultValue(
                                new TranslatedString()
                                    .setLanguage("en-US")
                                    .setValue("Origin name")))
                    .setDepartureDateTime("2020-04-12T16:20:50.52Z")
                    .setArrivalDateTime("2020-04-12T20:20:50.52Z")
                    .setFareName(
                        new LocalizedString()
                            .setDefaultValue(
                                new TranslatedString()
                                    .setLanguage("en-US")
                                    .setValue("Fare name"))));

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

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

PHP

PHP ile entegrasyonunuzu başlatmak için kod örneklerini inceleyin.

/**
 * 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/transit-passes/qr-code/rest/v1/transitobject
    $batchObject = new TransitObject([
      '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
        ])
      ],
      'passengerType' => 'SINGLE_PASSENGER',
      'passengerNames' => 'Passenger names',
      'tripType' => 'ONE_WAY',
      'ticketLeg' => new TicketLeg([
        'originStationCode' => 'LA',
        'originName' => new LocalizedString([
          'defaultValue' => new TranslatedString([
            'language' => 'en-US',
            'value' => 'Origin name'
          ])
        ]),
        'destinationStationCode' => 'SFO',
        'destinationName' => new LocalizedString([
          'defaultValue' => new TranslatedString([
            'language' => 'en-US',
            'value' => 'Destination name'
          ])
        ]),
        'departureDateTime' => '2020-04-12T16:20:50.52Z',
        'arrivalDateTime' => '2020-04-12T20:20:50.52Z',
        'fareName' => new LocalizedString([
          'defaultValue' => new TranslatedString([
            'language' => 'en-US',
            'value' => 'Fare name'
          ])
        ])
      ])
    ]);

    $batch->add($this->service->transitobject->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 ile entegrasyonunuzu başlatmak için kod örneklerini inceleyin.

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/transit-passes/qr-code/rest/v1/transitobject
        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
            }],
            'passengerType': 'SINGLE_PASSENGER',
            'passengerNames': 'Passenger names',
            'tripType': 'ONE_WAY',
            'ticketLeg': {
                'originStationCode': 'LA',
                'originName': {
                    'defaultValue': {
                        'language': 'en-US',
                        'value': 'Origin name'
                    }
                },
                'destinationStationCode': 'SFO',
                'destinationName': {
                    'defaultValue': {
                        'language': 'en-US',
                        'value': 'Destination name'
                    }
                },
                'departureDateTime': '2020-04-12T16:20:50.52Z',
                'arrivalDateTime': '2020-04-12T20:20:50.52Z',
                'fareName': {
                    'defaultValue': {
                        'language': 'en-US',
                        'value': 'Fare name'
                    }
                }
            }
        }

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

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

    print('Batch complete')

C#

C# ile entegrasyonunuzu başlatmak için kod örneklerini inceleyin.

/// <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/transit-passes/qr-code/rest/v1/transitobject
    TransitObject batchObject = new TransitObject
    {
      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
        }
      },
      PassengerType = "SINGLE_PASSENGER",
      PassengerNames = "Passenger names",
      TripType = "ONE_WAY",
      TicketLeg = new TicketLeg
      {
        OriginStationCode = "LA",
        OriginName = new LocalizedString
        {
          DefaultValue = new TranslatedString
          {
            Language = "en-US",
            Value = "Origin name"
          }
        },
        DestinationStationCode = "SFO",
        DestinationName = new LocalizedString
        {
          DefaultValue = new TranslatedString
          {
            Language = "en-US",
            Value = "Destination name"
          }
        },
        DepartureDateTime = "2020-04-12T16:20:50.52Z",
        ArrivalDateTime = "2020-04-12T20:20:50.52Z",
        FareName = new LocalizedString
        {
          DefaultValue = new TranslatedString
          {
            Language = "en-US",
            Value = "Fare name"
          }
        }
      }
    };

    data += "--batch_createobjectbatch\n";
    data += "Content-Type: application/json\n\n";
    data += "POST /walletobjects/v1/transitObject/\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

Düğüm ile entegrasyonunuzu başlatmak için kod örneklerini inceleyin.

/**
 * 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/transit-passes/qr-code/rest/v1/transitobject
    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
        }
      ],
      'passengerType': 'SINGLE_PASSENGER',
      'passengerNames': 'Passenger names',
      'tripType': 'ONE_WAY',
      'ticketLeg': {
        'originStationCode': 'LA',
        'originName': {
          'defaultValue': {
            'language': 'en-US',
            'value': 'Origin name'
          }
        },
        'destinationStationCode': 'SFO',
        'destinationName': {
          'defaultValue': {
            'language': 'en-US',
            'value': 'Destination name'
          }
        },
        'departureDateTime': '2020-04-12T16:20:50.52Z',
        'arrivalDateTime': '2020-04-12T20:20:50.52Z',
        'fareName': {
          'defaultValue': {
            'language': 'en-US',
            'value': 'Fare name'
          }
        }
      }
    };

    data += '--batch_createobjectbatch\n';
    data += 'Content-Type: application/json\n\n';
    data += 'POST /walletobjects/v1/transitObject\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 entegrasyonunuzu başlatmak için GitHub'daki eksiksiz kod örneklerimize göz atın kod örneklerini inceleyin.

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

		transitObject := new(walletobjects.TransitObject)
		transitObject.Id = fmt.Sprintf("%s.%s", issuerId, objectSuffix)
		transitObject.ClassId = fmt.Sprintf("%s.%s", issuerId, classSuffix)
		transitObject.State = "ACTIVE"
		transitObject.PassengerNames = "Passenger names"
		transitObject.TripType = "ONE_WAY"
		transitObject.PassengerType = "SINGLE_PASSENGER"
		transitObject.TicketLeg = &walletobjects.TicketLeg{
			DestinationStationCode: "SFO",
			OriginStationCode:      "LA",
		}

		transitJson, _ := json.Marshal(transitObject)
		batchObject := fmt.Sprintf("%s", transitJson)

		data += "--batch_createobjectbatch\n"
		data += "Content-Type: application/json\n\n"
		data += "POST /walletobjects/v1/transitObject\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)
	}
}