Entpacken der Nutzlast für Pub/Sub-Push-Abos

Beim Erstellen Ihres Pub/Sub-Systems kann das Entpacken der Nutzlast helfen die Sie mit anderen Systemen verbinden, die nicht alle Systemanforderungen eines Standardimplementierung von Pub/Sub-Push-Endpunkten.

Im Folgenden sind einige mögliche Anwendungsfälle für das Entpacken der Nutzlast aufgeführt:

  • Sie möchten keinen Pub/Sub-spezifischen Code zum Parsen von Nachrichten schreiben, für Ihre HTTP-Push-Endpunkte.
  • Sie bevorzugen den Empfang von Pub/Sub-Nachrichtenmetadaten als HTTP-Header. anstelle der Metadaten im HTTP-POST-Textkörper.
  • Sie möchten Pub/Sub-Nachrichten senden und ausschließen, die Pub/Sub-Metadaten enthalten, z. B. beim Senden von Daten an eine Drittanbieter-API.

So funktioniert das Entpacken der Nutzlast

Das Entpacken der Nutzlast ist ein Feature, das Pub/Sub entfernt. Nachrichten aller Metadaten der Nachricht mit Ausnahme der Nachrichtendaten. Durch Senden von Rohdaten Nachrichtendaten versenden, können Abonnenten die Nachricht verarbeiten, ohne sich an Systemanforderungen von Pub/Sub.

  • Beim Entpacken der Nutzlast werden die Nachrichtendaten direkt als HTTP Textkörper.
  • Ohne Entpacken der Nutzlast liefert Pub/Sub ein JSON-Objekt, enthält mehrere Metadatenfelder für die Nachricht und ein Nachrichtendatenfeld. In dieser muss das JSON-Format geparst werden, um die Nachrichtendaten abzurufen, und anschließend base64. decodiert werden.

Metadaten schreiben

Nach dem Aktivieren des Entpackens der Nutzlast können Sie die Option Metadaten schreiben verwenden, fügt zuvor entfernte Nachrichtenmetadaten dem Anfrageheader hinzu.

  • Schreibmetadaten aktiviert. Metadaten der Nachricht wieder der Anfrage hinzufügen Header. Sendet außerdem die decodierten Rohdaten der Nachricht.
  • Schreibmetadaten deaktiviert. Sendet nur die decodierten Rohdaten der Nachricht.

Schreibmetadaten werden über Pub/Sub, die Google Cloud CLI bereitgestellt Argument --push-no-wrapper-write-metadata und die API-Property NoWrapper. Standardmäßig ist dieser Wert null.

Hinweise

Beispiel für umschlossene und unverpackte Nachrichten

Die folgenden Beispiele veranschaulichen den Unterschied zwischen dem Senden einer umschlossene und entpackte HTTP-Nachricht. In diesen Beispielen enthalten die Nachrichtendaten den String {"status": "Hello there"}.

In diesem Beispiel wird ein Abo mit dem Entpacken der Nutzlast erstellt. aktiviert und veröffentlicht eine Nachricht in mytopic. Dabei wird eine Sortierung Schlüssel mit dem Wert some-key und der Medientyp ist deklariert als application/json.

gcloud pubsub topics publish mytopic
   --message='{"status": "Hello there"}'
   --ordering-key="some-key"
   --attribute "Content-Type=application/json"

In den folgenden Abschnitten wird der Unterschied zwischen zusammengefassten und nicht umgebrochenen Texten dargestellt. angezeigt.

Umgebrochene Nachricht

Das folgende Beispiel zeigt eine umschlossene Pub/Sub-Standardnachricht. In In diesem Fall ist das Entpacken von Payloading nicht aktiviert.

Veröffentlichen Push-Endpunkt empfängt
data="{"status": "Hello there"}"
ordering_key="some-key"
attributes=
  {
     {"Content-Type", "application/json"}
  }
Content-Length: 361
Content-Type: application/json
User-Agent: CloudPubSub-Google
Host: subscription-project.uc.r.appspot.com

{
  "message": {
      "attributes": {
          "Content-Type": "application/json"
      },
      "data": "eyJzdGF0dXMiOiAiSGVsbG8gdGhlcmUifQ==", //  Base64 - {"status": "Hello there"}
      "messageId": "2070443601311540",
      "message_id": "2070443601311540",
      "publishTime": "2021-02-26T19:13:55.749Z",
      "publish_time": "2021-02-26T19:13:55.749Z"
  },
  "subscription": "projects/myproject/..."
}

Unumschlossene Nachricht mit deaktiviertem Schreiben von Metadaten

Das folgende Beispiel zeigt eine unverpackte Nachricht mit der Option „Metadaten schreiben“ deaktiviert. In diesem Fall werden die x-goog-pubsub-*-Header und Nachrichtenattribute enthalten sind.

Veröffentlichen Push-Endpunkt empfängt
data="{"status": "Hello there"}"
ordering_key="some-key"
attributes=
  {
     {"Content-Type", "application/json"}
  }
Content-Length: 25
User-Agent: CloudPubSub-Google
Host: subscription-project.uc.r.appspot.com

{"status": "Hello there"}

Unumschlossene Nachricht mit aktivierter Option „Metadaten schreiben“

Das folgende Beispiel zeigt eine unverpackte Nachricht mit der Option „Metadaten schreiben“ aktiviert. In diesem Fall werden die x-goog-pubsub-*-Header und Nachrichtenattribute enthalten sind.

Veröffentlichen Push-Endpunkt empfängt
data="{"status": "Hello there"}"
ordering_key="some-key"
attributes=
  {
     {"Content-Type", "application/json"}
  }
x-goog-pubsub-subscription-name: "projects/myproject/..."
x-goog-pubsub-message-id: "2070443601311540"
x-goog-pubsub-publish-time: "2021-02-26T19:13:55.749Z"
x-goog-pubsub-ordering-key: "some-key"
Content-Type: application/json
Content-Length: 12
User-Agent: CloudPubSub-Google
Host: subscription-project.uc.r.appspot.com

{"status": "Hello there"}

Entpacken der Nutzlast konfigurieren

Sie können das Entpacken von Nutzlasten und Push-Zustellung für ein Abo aktivieren über die Seite Abodetails der Google Cloud Console, die Google Cloud CLI, oder die Client-Bibliotheken.

Console

  1. Öffnen Sie in der Google Cloud Console die Seite Abos.

    Pub/Sub-Abos öffnen

  2. Klicken Sie auf Abo erstellen.

  3. Geben Sie im Feld Abo-ID einen Namen ein.

    Weitere Informationen zur Benennung von Abos finden Sie unter Richtlinien für die Benennung von Themen oder Abos.

  4. Wählen Sie im Drop-down-Menü ein Thema aus. Das Abo empfängt Nachrichten aus dem Thema.

  5. Wählen Sie als Zustellungstyp die Option Push aus.

  6. Um das Entpacken der Nutzlast zu aktivieren, wählen Sie Entpacken der Nutzlast aktivieren aus.

  7. Optional: Um die Metadaten von Nachrichten im Anfrageheader beizubehalten, wählen Sie Metadaten schreiben aus. Sie müssen diese Option aktivieren, um einen Content-Type-Header festzulegen. für Ihre Nachrichten.

  8. Geben Sie eine Endpunkt-URL an.

  9. Behalten Sie alle anderen Standardwerte bei.

  10. Klicken Sie auf Erstellen.

gcloud

Um ein Abo mit Entpacken der Nutzlast zu konfigurieren, das Standard HTTP-Header, führen Sie den folgenden gcloud pubsub subscriptions create aus Befehl:

gcloud pubsub subscriptions create SUBSCRIPTION \
  --topic TOPIC \
  --push-endpoint=PUSH_ENDPOINT \
  --push-no-wrapper

Ersetzen Sie Folgendes:

  • SUBSCRIPTION: der Name oder die ID Ihres Pull-Abos.
  • TOPIC: die ID des Themas.
  • PUSH_ENDPOINT: die URL, die als Endpunkt verwendet werden soll Abo. z. B. https://myproject.appspot.com/myhandler.
  • --push-no-wrapper: Sendet die Nachrichtendaten direkt als HTTP-Text.

Um ein Abo mit Entpacken der Nutzlast zu konfigurieren und die Verwendung von x-goog-pubsub-*-Headern, führen Sie den folgenden Befehl aus:

gcloud pubsub subscriptions create SUBSCRIPTION \
  --topic TOPIC \
  --push-endpoint=PUSH_ENDPOINT \
  --push-no-wrapper \
  --push-no-wrapper-write-metadata
  • --push-no-wrapper-write-metadata: Wenn „true“, wird der Pub/Sub-Nachrichtenmetadaten für x-goog-pubsub-<KEY>:<VAL> der HTTP-Anfrage. Pub/Sub-Nachricht schreiben <KEY>:<VAL>-Headern der HTTP-Anfrage.

Python

Bevor Sie dieses Beispiel testen, folgen Sie der Einrichtungsanleitung für Python in der Schnellstart-Anleitung: Clientbibliotheken verwenden. Weitere Informationen finden Sie in der Referenzdokumentation zu Pub/Sub Python API.

from google.cloud import pubsub_v1

# TODO(developer)
# project_id = "your-project-id"
# topic_id = "your-topic-id"
# subscription_id = "your-subscription-id"
# endpoint = "https://my-test-project.appspot.com/push"

publisher = pubsub_v1.PublisherClient()
subscriber = pubsub_v1.SubscriberClient()
topic_path = publisher.topic_path(project_id, topic_id)
subscription_path = subscriber.subscription_path(project_id, subscription_id)

no_wrapper = pubsub_v1.types.PushConfig.NoWrapper(write_metadata=True)
push_config = pubsub_v1.types.PushConfig(
    push_endpoint=endpoint, no_wrapper=no_wrapper
)

# Wrap the subscriber in a 'with' block to automatically call close() to
# close the underlying gRPC channel when done.
with subscriber:
    subscription = subscriber.create_subscription(
        request={
            "name": subscription_path,
            "topic": topic_path,
            "push_config": push_config,
        }
    )

print(f"Push no wrapper subscription created: {subscription}.")
print(f"Endpoint for subscription is: {endpoint}")
print(f"No wrapper configuration for subscription is: {no_wrapper}")

Java

Bevor Sie dieses Beispiel testen, folgen Sie der Einrichtungsanleitung für Java in der Kurzanleitung: Clientbibliotheken verwenden. Weitere Informationen finden Sie in der Referenzdokumentation zu Pub/Sub Java API.

/*
 * Copyright 2016 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package pubsub;


import com.google.cloud.pubsub.v1.SubscriptionAdminClient;
import com.google.pubsub.v1.PushConfig;
import com.google.pubsub.v1.PushConfig.NoWrapper;
import com.google.pubsub.v1.Subscription;
import com.google.pubsub.v1.SubscriptionName;
import com.google.pubsub.v1.TopicName;
import java.io.IOException;

public class CreateUnwrappedPushSubscriptionExample {
  public static void main(String... args) throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-project-id";
    String subscriptionId = "your-subscription-id";
    String topicId = "your-topic-id";
    String pushEndpoint = "https://my-test-project.appspot.com/push";

    createPushSubscriptionExample(projectId, subscriptionId, topicId, pushEndpoint);
  }

  public static void createPushSubscriptionExample(
      String projectId, String subscriptionId, String topicId, String pushEndpoint)
      throws IOException {
    try (SubscriptionAdminClient subscriptionAdminClient = SubscriptionAdminClient.create()) {
      TopicName topicName = TopicName.of(projectId, topicId);
      SubscriptionName subscriptionName = SubscriptionName.of(projectId, subscriptionId);
      NoWrapper noWrapper =
          NoWrapper.newBuilder()
              // Determines if message metadata is added to the HTTP headers of
              // the delivered message.
              .setWriteMetadata(true)
              .build();
      PushConfig pushConfig =
          PushConfig.newBuilder().setPushEndpoint(pushEndpoint).setNoWrapper(noWrapper).build();

      // Create a push subscription with default acknowledgement deadline of 10 seconds.
      // Messages not successfully acknowledged within 10 seconds will get resent by the server.
      Subscription subscription =
          subscriptionAdminClient.createSubscription(subscriptionName, topicName, pushConfig, 10);
      System.out.println("Created push subscription: " + subscription.getName());
    }
  }
}

C++

Bevor Sie dieses Beispiel testen, folgen Sie der Einrichtungsanleitung für C++ in der Kurzanleitung: Clientbibliotheken verwenden. Weitere Informationen finden Sie in der Referenzdokumentation zur Pub/Sub C++ API.

namespace pubsub = ::google::cloud::pubsub;
namespace pubsub_admin = ::google::cloud::pubsub_admin;
[](pubsub_admin::SubscriptionAdminClient client,
   std::string const& project_id, std::string const& topic_id,
   std::string const& subscription_id, std::string const& endpoint) {
  google::pubsub::v1::Subscription request;
  request.set_name(
      pubsub::Subscription(project_id, subscription_id).FullName());
  request.set_topic(pubsub::Topic(project_id, topic_id).FullName());
  request.mutable_push_config()->set_push_endpoint(endpoint);
  request.mutable_push_config()->mutable_no_wrapper()->set_write_metadata(
      true);
  auto sub = client.CreateSubscription(request);
  if (sub.status().code() == google::cloud::StatusCode::kAlreadyExists) {
    std::cout << "The subscription already exists\n";
    return;
  }
  if (!sub) throw std::move(sub).status();

  std::cout << "The subscription was successfully created: "
            << sub->DebugString() << "\n";
}

Go

Bevor Sie dieses Beispiel testen, folgen Sie der Einrichtungsanleitung für Go in der Schnellstart-Anleitung: Clientbibliotheken verwenden. Weitere Informationen finden Sie in der Referenzdokumentation zu Pub/Sub Go API.

import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/pubsub"
)

// createPushNoWrapperSubscription creates a push subscription where messages are delivered in the HTTP body.
func createPushNoWrapperSubscription(w io.Writer, projectID, subID string, topic *pubsub.Topic, endpoint string) error {
	// projectID := "my-project-id"
	// subID := "my-sub"
	// topic of type https://godoc.org/cloud.google.com/go/pubsub#Topic
	// endpoint := "https://my-test-project.appspot.com/push"
	ctx := context.Background()
	client, err := pubsub.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("pubsub.NewClient: %w", err)
	}
	defer client.Close()

	sub, err := client.CreateSubscription(ctx, subID, pubsub.SubscriptionConfig{
		Topic:       topic,
		AckDeadline: 10 * time.Second,
		PushConfig: pubsub.PushConfig{
			Endpoint: endpoint,
			Wrapper: &pubsub.NoWrapper{
				// Determines if message metadata is added to the HTTP headers of
				// the delivered message.
				WriteMetadata: true,
			},
		},
	})
	if err != nil {
		return fmt.Errorf("CreateSubscription: %w", err)
	}
	fmt.Fprintf(w, "Created push no wrapper subscription: %v\n", sub)
	return nil
}

Node.js

Bevor Sie dieses Beispiel testen, folgen Sie der Einrichtungsanleitung für PHP in der Schnellstart-Anleitung: Clientbibliotheken verwenden. Weitere Informationen finden Sie in der Referenzdokumentation zu Pub/Sub Node.js API.

/**
 * TODO(developer): Uncomment these variables before running the sample.
 */
// const pushEndpoint = 'YOUR_ENDPOINT_URL';
// const topicNameOrId = 'YOUR_TOPIC_NAME_OR_ID';
// const subscriptionNameOrId = 'YOUR_SUBSCRIPTION_NAME_OR_ID';

// Imports the Google Cloud client library
const {PubSub} = require('@google-cloud/pubsub');

// Creates a client; cache this for further use
const pubSubClient = new PubSub();

async function createPushSubscriptionNoWrapper(
  pushEndpoint,
  topicNameOrId,
  subscriptionNameOrId
) {
  const options = {
    pushConfig: {
      // Set to an HTTPS endpoint of your choice. If necessary, register
      // (authorize) the domain on which the server is hosted.
      pushEndpoint,
      // When true, writes the Pub/Sub message metadata to
      // `x-goog-pubsub-<KEY>:<VAL>` headers of the HTTP request. Writes the
      // Pub/Sub message attributes to `<KEY>:<VAL>` headers of the HTTP request.
      noWrapper: {
        writeMetadata: true,
      },
    },
  };

  await pubSubClient
    .topic(topicNameOrId)
    .createSubscription(subscriptionNameOrId, options);
  console.log(`Subscription ${subscriptionNameOrId} created.`);
}

Node.js

Bevor Sie dieses Beispiel testen, folgen Sie der Einrichtungsanleitung für PHP in der Schnellstart-Anleitung: Clientbibliotheken verwenden. Weitere Informationen finden Sie in der Referenzdokumentation zu Pub/Sub Node.js API.

/**
 * TODO(developer): Uncomment these variables before running the sample.
 */
// const pushEndpoint = 'YOUR_ENDPOINT_URL';
// const topicNameOrId = 'YOUR_TOPIC_NAME_OR_ID';
// const subscriptionNameOrId = 'YOUR_SUBSCRIPTION_NAME_OR_ID';

// Imports the Google Cloud client library
import {PubSub, CreateSubscriptionOptions} from '@google-cloud/pubsub';

// Creates a client; cache this for further use
const pubSubClient = new PubSub();

async function createPushSubscriptionNoWrapper(
  pushEndpoint: string,
  topicNameOrId: string,
  subscriptionNameOrId: string
) {
  const options: CreateSubscriptionOptions = {
    pushConfig: {
      // Set to an HTTPS endpoint of your choice. If necessary, register
      // (authorize) the domain on which the server is hosted.
      pushEndpoint,
      // When true, writes the Pub/Sub message metadata to
      // `x-goog-pubsub-<KEY>:<VAL>` headers of the HTTP request. Writes the
      // Pub/Sub message attributes to `<KEY>:<VAL>` headers of the HTTP request.
      noWrapper: {
        writeMetadata: true,
      },
    },
  };

  await pubSubClient
    .topic(topicNameOrId)
    .createSubscription(subscriptionNameOrId, options);
  console.log(`Subscription ${subscriptionNameOrId} created.`);
}

Header für Inhaltstyp in der Nachricht festlegen

Nachdem das Entpacken der Nutzlast aktiviert ist, automatisch ein Medientyp-Header-Feld in Ihrer Anfrage festlegen. Wenn Sie Content-Type-Header-Feld nicht explizit festlegen, kann durch die Verarbeitung Ihrer Anfrage der Standardwert application/octet-stream oder die Anfrage auf unerwartete Weise interpretieren.

Wenn ein Content-Type-Header erforderlich ist, müssen Sie ihn explizit deklarieren Veröffentlichungszeitpunkt für jede einzelne veröffentlichte Nachricht an. Dazu müssen Sie aktivieren Sie zuerst Metadaten schreiben. Dieses Ergebnis der Aktivierung von Metadaten schreiben finden Sie in den bereitgestellten Beispielen.

Nächste Schritte