Tipps zur Leistungsoptimierung

In diesem Dokument werden einige Techniken beschrieben, mit denen Sie die Leistung Ihrer Anwendung verbessern können. In einigen Fällen werden Beispiele aus anderen APIs oder generischen APIs verwendet, um die vorgestellten Ideen zu erläutern. Die gleichen Konzepte gelten jedoch auch für die Google Wallet API.

Komprimierung mit gzip

Durch Aktivierung der gzip-Komprimierung kann die für jede Anfrage benötigte Bandbreite einfach und bequem reduziert werden. Auch wenn die Dekomprimierung der Ergebnisse zusätzliche CPU-Zeit kostet, lohnt sie sich verglichen mit den Netzwerkkosten durchaus.

Sie müssen zwei Schritte ausführen, um eine mit gzip codierte Antwort zu erhalten: Legen Sie einen Header Accept-Encoding fest und ändern Sie den User-Agent so, dass er den String gzip enthält. Hier ein Beispiel für HTTP-Header im korrekten Format zur Aktivierung der gzip-Komprimierung:

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

Mit Teilressourcen arbeiten

Eine andere Möglichkeit zur Verbesserung der Leistung der API-Aufrufe besteht darin, nur den Teil der Daten zu senden und zu empfangen, der für Sie interessant ist. Dadurch lassen sich in der Anwendung die Übertragung, Analyse und Speicherung nicht benötigter Felder vermeiden und so Ressourcen wie Netzwerke, CPU und Speicher effizienter nutzen.

Es gibt zwei Arten von Teilanfragen:

  • Teilantwort: Eine Anfrage, mit der Sie angeben, welche Felder in der Antwort enthalten sein sollen. Verwenden Sie dazu den Anfrageparameter fields.
  • Patch: Eine Aktualisierungsanfrage, bei der Sie nur die zu ändernden Felder senden. Verwenden Sie dazu das HTTP-Verb PATCH.

In den folgenden Abschnitten finden Sie weitere Informationen zu Teilanfragen.

Teilantwort

Standardmäßig wird vom Server nach der Verarbeitung einer Anfrage die komplette Darstellung einer Ressource zurückgeliefert. Sie können den Server zwecks Leistungsverbesserung aber auch anweisen, nur die Felder zu senden, die Sie wirklich benötigen, und erhalten dann eine Teilantwort.

Verwenden Sie zum Anfragen einer Teilantwort den Anfrageparameter fields, um anzugeben, welche Felder zurückgegeben werden sollen. Sie können diesen Parameter mit jeder beliebigen Anfrage verwenden, die Antwortdaten zurückgibt.

Beachten Sie, dass sich der fields-Parameter nur auf die Antwortdaten auswirkt. Er wirkt sich nicht auf die Daten aus, die Sie (gegebenenfalls) senden müssen. Verwenden Sie eine Patch-Anfrage, um die Datenmenge zu reduzieren, die bei der Änderung von Ressourcen gesendet wird.

Beispiel

Das folgende Beispiel zeigt die Verwendung des fields-Parameters mit einer allgemeinen (fiktiven) "Demo"-API.

Einfache Anfrage: Bei dieser HTTP-GET-Anfrage wird der Parameter fields weggelassen und die vollständige Ressource zurückgegeben.

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

Antwort mit vollständiger Ressource: Die vollständigen Ressourcendaten umfassen folgende Felder sowie zahlreiche weitere Felder, die der Übersichtlichkeit halber ausgelassen wurden.

{
  "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",
    ...
  },
  ...
  ]
}

Anfrage für eine Teilantwort: In der folgenden Anfrage für dieselbe Ressource wird der Parameter fields verwendet, um die zurückgegebene Datenmenge erheblich zu verringern.

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

Teilantwort: Als Antwort auf die obige Anfrage sendet der Server eine Antwort zurück, die zusammen mit einem einfachen Array nur die Art von Informationen enthält, die ausschließlich HTML-Titel und Längeneigenschaften in jedem Element umfassen.

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

Bei der Antwort handelt es sich um ein JSON-Objekt, das nur die ausgewählten Felder und deren einschließende übergeordnete Objekte enthält.

Details zur Formatierung des fields-Parameters werden als Nächstes beschrieben, gefolgt von weiteren Informationen zum genauen Inhalt, der in der Antwort zurückgegeben wird.

Parameter "Fields" – Syntaxzusammenfassung

Das Format des fields-Anfrageparameters basiert grob auf der XPath-Syntax. Die unterstützte Syntax wird unten zusammengefasst. Zusätzliche Beispiele finden Sie im darauffolgenden Abschnitt.

  • Zur Auswahl mehrerer Felder verwenden Sie eine durch Kommas getrennte Liste.
  • Verwenden Sie a/b, um ein Feld b auszuwählen, das im Feld a verschachtelt ist; verwenden Sie a/b/c, um ein Feld c auszuwählen, das in b verschachtelt ist.

    Ausnahme: Bei API-Antworten mit "data"-Wrappern, bei denen die Antwort in einem Objekt vom Typ data in der Form data: { ... } verschachtelt ist, darf "data" nicht in die Spezifikation von fields aufgenommen werden. Die Aufnahme eines Datenobjekts in einer Feldspezifikation wie data/a/b führt zu einem Fehler. Verwenden Sie stattdessen eine fields-Angabe wie a/b.

  • Verwenden Sie ein untergeordnetes Auswahlzeichen, um eine Reihe von untergeordneten Feldern von Arrays oder Objekten anzufordern, indem Sie Ausdrücke in Klammern "( )" setzen.

    Beispiel: fields=items(id,author/email) gibt nur die Element-ID und die E-Mail-Adresse des Autors für jedes Element im Array zurück. Sie können auch ein einzelnes Teilfeld angeben, in dem fields=items(id) fields=items/id entspricht.

  • Verwenden Sie gegebenenfalls Platzhalter bei der Feldauswahl.

    Zum Beispiel: Mit fields=items/pagemap/* werden alle Objekte in einer Pagemap ausgewählt.

Weitere Beispiele zur Verwendung des Parameters "Fields"

In diesen Beispielen wird auch beschrieben, wie sich der Wert des Parameters fields auf die Antwort auswirkt.

Hinweis: Wie bei allen Abfrageparameterwerten muss der Wert des Parameters fields URL-codiert sein. Die Beispiele in diesem Dokument enthalten für eine bessere Lesbarkeit keine Codierung.

Identifizieren Sie die Felder, die zurückgegeben werden sollen, oder treffen Sie eine Feldauswahl.
Der Wert des Anfrageparameters fields besteht aus einer durch Kommas getrennten Liste mit Feldern. Jedes Feld muss relativ zum Stamm der Antwort angegeben werden. Wenn Sie also einen list-Vorgang ausführen, besteht die Antwort aus einer Sammlung und enthält im Allgemeinen ein Ressourcen-Array. Bei einem Vorgang, der eine einzelne Ressource zurückgibt, werden die Felder bezogen auf diese Ressource angegeben. Wenn das ausgewählte Feld ein Array (oder ein Teil eines Arrays) ist, gibt der Server den ausgewählten Teil aller Elemente in dem Array zurück.

Hier einige Beispiele für die Sammlungsebene:
Beispiele Effekt
items Gibt alle Elemente im Element-Array zurück, einschließlich aller Felder in jedem Element, jedoch keine anderen Felder.
etag,items Gibt sowohl das etag-Feld als auch alle Elemente im Element-Array zurück.
items/title Gibt nur das title-Feld für alle Elemente im Element-Array zurück.

Wenn ein verschachteltes Feld zurückgegeben wird, umfasst die Antwort die einschließenden übergeordneten Objekte. Die übergeordneten Felder enthalten nur dann andere untergeordnete Felder, wenn diese ausdrücklich ausgewählt wurden.
context/facets/label Gibt nur das Feld label für alle Mitglieder des Arrays facets zurück, das selbst unter dem Objekt context verschachtelt ist.
items/pagemap/*/title Gibt für jedes Element im Element-Array nur das title-Feld (sofern vorhanden) aller Objekte zurück, die untergeordnete Objekte von pagemap sind.

Hier einige Beispiele für die Ressourcenebene:
Beispiele Effekt
title Gibt das Feld title der angeforderten Ressource zurück.
author/uri Gibt das Unterfeld uri des Objekts author in der angeforderten Ressource zurück.
links/*/href
Gibt das Feld href aller Objekte zurück, die untergeordnete Objekte von links sind.
Mit der untergeordneten Auswahl fordern Sie nur Teile bestimmter Felder an.
Wenn in Ihrer Anfrage bestimmte Felder spezifiziert werden, gibt der Server standardmäßig die Objekte oder Array-Elemente in ihrer Gesamtheit zurück. Sie können eine Antwort angeben, die nur bestimmte untergeordnete Felder enthält. Dazu verwenden Sie die Syntax "( )" für die untergeordnete Auswahl wie im folgenden Beispiel dargestellt.
Beispiel Effekt
items(title,author/uri) Gibt nur die Werte von title und den uri des Autors für jedes Element im Element-Array zurück.

Umgang mit Teilantworten

Nachdem ein Server eine gültige Anfrage verarbeitet hat, die den fields-Abfrageparameter enthält, sendet er einen 200 OK-HTTP-Statuscode zusammen mit den angeforderten Daten zurück. Wenn der fields-Abfrageparameter einen Fehler enthält oder ungültig ist, gibt der Server einen 400 Bad Request-HTTP-Statuscode zusammen mit einer Fehlermeldung zurück, die den Nutzer darüber informiert, was bei seiner Feldauswahl falsch war (Beispiel: "Invalid field selection a/b").

Hier ein Beispiel für eine Teilantwort, die im einführenden Abschnitt oben dargestellt wurde. Mit dem Parameter fields gibt die Anfrage an, welche Felder zurückgegeben werden sollen.

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

Die Teilantwort sieht folgendermaßen aus:

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

Hinweis: Bei APIs, die Abfrageparameter für die Datenpaginierung (wie beispielsweise maxResults und nextPageToken) unterstützen, können Sie mit diesen Parametern die Ergebnisse der einzelnen Abfragen auf eine überschaubare Größe reduzieren. Andernfalls wären Leistungssteigerungen mit einer Teilantwort eventuell nicht realisierbar.

Patch (Teilaktualisierung)

Sie können auch das Senden von unnötigen Daten vermeiden, wenn Sie Ressourcen ändern. Um nur aktualisierte Daten für die Felder zu senden, die Sie ändern, verwenden Sie das HTTP-Verb PATCH. Die Patch-Semantik, die in diesem Dokument beschrieben wird, ist anders (und einfacher) als die der älteren GData-Implementierung einer Teilaktualisierung.

Das kurze Beispiel unten zeigt, wie mit einer Patch-Anfrage die Datenmenge minimiert wird, die Sie zur Durchführung eines kleinen Updates benötigen.

Beispiel

Dieses Beispiel zeigt eine einfache Patch-Anfrage, mit der nur der Titel einer allgemeinen (fiktiven) "Demo"-API-Ressource aktualisiert werden soll. Die Ressource enthält auch einen Kommentar, eine Reihe von Eigenschafts-, Status- und viele andere Felder. Diese Anfrage sendet jedoch nur das Feld title, da dieses Feld als einziges geändert wird:

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

{
  "title": "New title"
}

Antwort

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

Der Server gibt einen 200 OK-Statuscode zusammen mit der vollständigen Darstellung der aktualisierten Ressource zurück. Da nur das Feld title in der Patch-Anfrage enthalten war, ist dies der einzige Wert, der sich von den vorherigen Werten unterscheidet.

Hinweis: Wenn Sie den Parameter fields einer Teilantwort in Verbindung mit einem Patch verwenden, können Sie Aktualisierungsanfragen noch weiter optimieren. Mit einer Patch-Anfrage wird nur die Größe der Anfrage reduziert. Eine Teilantwort reduziert die Größe der Antwort. Um also die in beiden Richtungen gesendete Datenmenge zu reduzieren, verwenden Sie eine Patch-Anfrage mit dem fields-Parameter.

Semantik einer Patch-Anfrage

Der Text der Patch-Anfrage umfasst nur die Ressourcenfelder, die Sie ändern möchten. Bei der Angabe eines Feldes müssen Sie einschließende übergeordnete Objekte einbeziehen, da die einschließenden übergeordneten Objekte mit einer Teilantwort zurückgegeben werden. Die geänderten Daten, die Sie senden, werden mit den Daten für das übergeordnete Objekt, sofern vorhanden, zusammengeführt.

  • Hinzufügen: Um ein Feld hinzuzufügen, das noch nicht vorhanden ist, geben Sie das neue Feld und dessen Wert an.
  • Ändern: Um den Wert eines vorhandenen Feldes zu ändern, geben Sie das Feld an und legen es auf den neuen Wert fest.
  • Löschen: Geben Sie das zu löschende Feld an und setzen Sie es auf null. Beispiel: "comment": null. Sie können auch ein ganzes Objekt löschen (wenn es änderbar ist), indem Sie es auf null setzen. Bei der Java API-Clientbibliothek verwenden Sie stattdessen Data.NULL_STRING. Weitere Informationen finden Sie unter JSON null.

Hinweis zu Arrays: Patch-Anfragen, die Arrays enthalten, ersetzen das vorhandene Array durch das Array, das Sie angeben. Sie können ein Array nicht stückweise ändern, hinzufügen oder löschen.

Patch in einem Read-Modify-Write-Zyklus verwenden

Es kann in der Praxis sinnvoll sein, wenn Sie als Erstes eine Teilantwort mit den Daten abrufen, die Sie ändern möchten. Dies ist besonders wichtig bei Ressourcen, die ETags verwenden, weil Sie den aktuellen ETag-Wert im HTTP-Header If-Match angeben müssen, um die Ressource erfolgreich zu aktualisieren. Nachdem Sie die Daten abgerufen haben, können Sie die gewünschten Werte ändern und die geänderte Teildarstellung mit einer Patch-Anfrage wieder zurücksenden. Beim folgenden Beispiel wird davon ausgegangen, dass die Demo-Ressource ETags verwendet:

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

Dies ist die Teilantwort:

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

Die folgende Patch-Anfrage basiert auf dieser Antwort. Wie unten dargestellt, verwendet die Anfrage auch den Parameter fields, um die in der Patch-Antwort zurückgegebenen Daten zu begrenzen:

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. */
  },
}

Der Server antwortet mit einem HTTP-Statuscode "200 OK" und der Teildarstellung der aktualisierten Ressource:

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. */
  }
}

Patch-Anfrage direkt erstellen

Einige Patch-Anfragen müssen auf den Daten aufbauen, die Sie vorher abgerufen haben. Beispiel: Wenn Sie ein Element einem Array hinzufügen und keines der vorhandenen Array-Elemente verlieren möchten, müssen Sie zuerst die vorhandenen Daten abrufen. Wenn eine API ETags verwendet, müssen Sie den vorherigen ETag-Wert mit der Anfrage senden, damit die Ressource erfolgreich aktualisiert werden kann.

Hinweis: Mit dem HTTP-Header "If-Match: *" können Sie einen Patch erzwingen, wenn ETags verwendet werden. In diesem Fall müssen Sie den Lesevorgang nicht vor dem Schreibvorgang ausführen.

In anderen Fällen können Sie die Patch-Anfrage direkt erstellen, ohne zuvor die vorhandenen Daten abzurufen. Beispiel: Sie können jederzeit eine Patch-Anfrage einrichten, die ein Feld mit einem neuen Wert aktualisiert oder ein neues Feld hinzufügt. Hier ein Beispiel:

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
  }
}

Wenn das Kommentarfeld bei dieser Anfrage einen vorhandenen Wert hat, überschreibt der neue Wert diesen. Ansonsten wird er auf den neuen Wert festgelegt. Wenn eine Volumeneigenschaft vorhanden war, wird ihr Wert ebenfalls überschrieben; wenn nicht, wird sie erstellt. Das Genauigkeitsfeld, falls festgelegt, wird entfernt.

Umgang mit der Antwort auf ein Patch

Nachdem eine gültige Patch-Anfrage verarbeitet wurde, gibt die API einen HTTP-Antwortcode 200 OK zusammen mit der vollständigen Darstellung der geänderten Ressource zurück. Wenn ETags von der API verwendet werden, aktualisiert der Server ETag-Werte, sobald eine Patch-Anfrage erfolgreich verarbeitet wird, wie bei PUT.

Die Patch-Anfrage gibt die vollständige Ressourcendarstellung zurück, es sei denn, Sie verwenden den fields-Parameter, um die zurückgegebene Datenmenge zu reduzieren.

Wenn eine Patch-Anfrage zu einem neuen Ressourcenstatus führt, der syntaktisch oder semantisch ungültig ist, gibt der Server einen HTTP-Statuscode 400 Bad Request oder 422 Unprocessable Entity zurück und der Ressourcenstatus bleibt unverändert. Beispiel: Wenn Sie versuchen, den Wert für ein Pflichtfeld zu löschen, gibt der Server einen Fehler zurück.

Alternative Schreibweise, wenn das PATCH-HTTP-Verb nicht unterstützt wird

Wenn Ihre Firewall keine HTTP-PATCH-Anfragen unterstützt, führen Sie eine HTTP-POST-Anfrage aus und setzen Sie den Override-Header auf PATCH (wie unten dargestellt):

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

Unterschied zwischen Patch und Aktualisierung

Wenn Sie in der Praxis Daten für eine Aktualisierungsanfrage senden, die das HTTP-Verb PUT verwendet, müssen Sie nur die Felder senden, die erforderlich oder optional sind. Wenn Sie Werte für Felder senden, die vom Server festgelegt werden, werden diese ignoriert. Obwohl dies wie eine andere Möglichkeit für eine Teilaktualisierung aussieht, hat dieser Ansatz einige Einschränkungen. Mit Aktualisierungen, die das HTTP-Verb PUT verwenden, schlägt die Anfrage fehl, wenn Sie erforderliche Parameter nicht angeben. Vorher festgelegte Daten werden gelöscht, wenn Sie keine optionalen Parameter angeben.

Aus diesem Grund ist die Verwendung eines Patch wesentlich sicherer. Sie geben nur Daten für die Felder an, die Sie ändern möchten; Felder, die Sie weglassen, werden nicht gelöscht. Sich wiederholende Elemente oder Arrays sind die einzige Ausnahme zu dieser Regel. Wenn Sie diese alle weglassen, bleiben sie unverändert. Wenn Sie ein Element oder Array angeben, wird das ganze Set durch das Set ersetzt, das Sie angeben.

Batchanfragen an Google Wallet

Die Google Wallet API unterstützt die Batchverarbeitung von API-Aufrufen, um die Anzahl der Aufrufe zu reduzieren. die ein Client herstellen muss. Weitere Informationen zu Batchanfragen und siehe Batchdetails.

Der folgende Beispielcode zeigt Batchanfragen. Java und PHP Beispiele für die Verwendung der Google Wallet- Bibliotheken, um das Erstellen von Klassen und Objekten zu vereinfachen.

Java

Um Ihre Integration in Java zu starten, lesen Sie unsere vollständige <ph type="x-smartling-placeholder"></ph> Codebeispiele auf GitHub

/**
 * 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<EventTicketObject> callback =
      new JsonBatchCallback<EventTicketObject>() {
        // Invoked if the request was successful
        public void onSuccess(EventTicketObject 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/events/rest/v1/eventticketobject
    EventTicketObject batchObject =
        new EventTicketObject()
            .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)))
            .setSeatInfo(
                new EventSeat()
                    .setSeat(
                        new LocalizedString()
                            .setDefaultValue(
                                new TranslatedString().setLanguage("en-US").setValue("42")))
                    .setRow(
                        new LocalizedString()
                            .setDefaultValue(
                                new TranslatedString().setLanguage("en-US").setValue("G3")))
                    .setSection(
                        new LocalizedString()
                            .setDefaultValue(
                                new TranslatedString().setLanguage("en-US").setValue("5")))
                    .setGate(
                        new LocalizedString()
                            .setDefaultValue(
                                new TranslatedString().setLanguage("en-US").setValue("A"))))
            .setTicketHolderName("Ticket holder name")
            .setTicketNumber("Ticket number");

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

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

PHP

Um mit der Integration in PHP zu beginnen, lesen Sie unsere vollständigen <ph type="x-smartling-placeholder"></ph> Codebeispiele auf GitHub

/**
 * 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/events/rest/v1/eventticketobject
    $batchObject = new EventTicketObject([
      '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
        ])
      ],
      'seatInfo' => new EventSeat([
        'seat' => new LocalizedString([
          'defaultValue' => new TranslatedString([
            'language' => 'en-US',
            'value' => '42'
          ])
        ]),
        'row' => new LocalizedString([
          'defaultValue' => new TranslatedString([
            'language' => 'en-US',
            'value' => 'G3'
          ])
        ]),
        'section' => new LocalizedString([
          'defaultValue' => new TranslatedString([
            'language' => 'en-US',
            'value' => '5'
          ])
        ]),
        'gate' => new LocalizedString([
          'defaultValue' => new TranslatedString([
            'language' => 'en-US',
            'value' => 'A'
          ])
        ])
      ]),
      'ticketHolderName' => 'Ticket holder name',
      'ticketNumber' => 'Ticket number'
    ]);

    $batch->add($this->service->eventticketobject->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

Informationen zum Starten Ihrer Integration in Python finden Sie in unserer vollständigen <ph type="x-smartling-placeholder"></ph> Codebeispiele auf GitHub

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/events/rest/v1/eventticketobject
        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
            }],
            'seatInfo': {
                'seat': {
                    'defaultValue': {
                        'language': 'en-US',
                        'value': '42'
                    }
                },
                'row': {
                    'defaultValue': {
                        'language': 'en-US',
                        'value': 'G3'
                    }
                },
                'section': {
                    'defaultValue': {
                        'language': 'en-US',
                        'value': '5'
                    }
                },
                'gate': {
                    'defaultValue': {
                        'language': 'en-US',
                        'value': 'A'
                    }
                }
            },
            'ticketHolderName': 'Ticket holder name',
            'ticketNumber': 'Ticket number'
        }

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

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

    print('Batch complete')

C#

Informationen zum Starten Ihrer Integration in C# finden Sie in unserer vollständigen <ph type="x-smartling-placeholder"></ph> Codebeispiele auf GitHub

/// <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/events/rest/v1/eventticketobject
    EventTicketObject batchObject = new EventTicketObject
    {
      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
        }
      },
      SeatInfo = new EventSeat
      {
        Seat = new LocalizedString
        {
          DefaultValue = new TranslatedString
          {
            Language = "en-US",
            Value = "42"
          }
        },
        Row = new LocalizedString
        {
          DefaultValue = new TranslatedString
          {
            Language = "en-US",
            Value = "G3"
          }
        },
        Section = new LocalizedString
        {
          DefaultValue = new TranslatedString
          {
            Language = "en-US",
            Value = "5"
          }
        },
        Gate = new LocalizedString
        {
          DefaultValue = new TranslatedString
          {
            Language = "en-US",
            Value = "A"
          }
        }
      },
      TicketHolderName = "Ticket holder name",
      TicketNumber = "Ticket number"
    };

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

Informationen zum Starten Ihrer Integration in Node.js finden Sie in unserer vollständigen <ph type="x-smartling-placeholder"></ph> Codebeispiele auf GitHub

/**
 * 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/events/rest/v1/eventticketobject
    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
        }
      ],
      'seatInfo': {
        'seat': {
          'defaultValue': {
            'language': 'en-US',
            'value': '42'
          }
        },
        'row': {
          'defaultValue': {
            'language': 'en-US',
            'value': 'G3'
          }
        },
        'section': {
          'defaultValue': {
            'language': 'en-US',
            'value': '5'
          }
        },
        'gate': {
          'defaultValue': {
            'language': 'en-US',
            'value': 'A'
          }
        },
      },
      'ticketHolderName': 'Ticket holder name',
      'ticketNumber': 'Ticket number'
    };

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

Ok

Informationen zum Starten der Integration in Go finden Sie in unseren vollständigen Codebeispielen auf GitHub <ph type="x-smartling-placeholder"></ph> Codebeispiele auf GitHub

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

		eventticketObject := new(walletobjects.EventTicketObject)
		eventticketObject.Id = fmt.Sprintf("%s.%s", issuerId, objectSuffix)
		eventticketObject.ClassId = fmt.Sprintf("%s.%s", issuerId, classSuffix)
		eventticketObject.TicketHolderName = "Ticket holder name"
		eventticketObject.TicketNumber = "Ticket number"
		eventticketObject.State = "ACTIVE"

		eventticketJson, _ := json.Marshal(eventticketObject)
		batchObject := fmt.Sprintf("%s", eventticketJson)

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