When building your Pub/Sub system, payload unwrapping can help you connect to other systems that don't adhere to all system requirements of a standard Pub/Sub push endpoint implementation.
Some potential use cases for payload unwrapping are as follows:
- You don't want to write Pub/Sub-specific message parsing code for your HTTP push endpoints.
- You prefer receiving Pub/Sub message metadata as HTTP headers instead of the metadata in the HTTP POST body.
- You want to send Pub/Sub messages and exclude the Pub/Sub metadata, for example when sending data to a third-party API.
How payload unwrapping works
Payload unwrapping is a feature that strips Pub/Sub messages of all message metadata, except for the message data. By sending raw message data, subscribers can process the message without having to adhere to any system requirements of Pub/Sub.
- With payload unwrapping, the message data is delivered directly as the HTTP body.
- Without payload unwrapping, Pub/Sub delivers a JSON object that contains multiple message metadata fields and a message data field. In this case, the JSON must be parsed to retrieve the message data and then base64 decoded.
Write metadata
After enabling payload unwrapping, you can use the write metadata option which adds previously removed message metadata into the request header.
- Write metadata enabled. Add message metadata back into the request header. Also delivers the raw, decoded message data.
- Write metadata disabled. Only delivers the raw, decoded message data.
Write metadata is exposed through the Pub/Sub, the Google Cloud CLI
argument --push-no-wrapper-write-metadata
, and the API property NoWrapper
.
By default, this value is null.
Before you begin
- Learn about Pub/Sub subscriptions and push subscriptions. Payload unwrapping can only be used with push subscriptions.
- Learn how to configure a push subscription.
Example for wrapped and unwrapped messages
The following examples illustrate the difference between sending a
wrapped and unwrapped HTTP message. In these examples, the message data contains
the string {"status": "Hello there"}
.
For this example, a subscription is created with the payload unwrapping
feature enabled and publishes a message to mytopic
. It uses an ordering
key with a value of some-key
and the media type is declared as
application/json
.
gcloud pubsub topics publish mytopic --message='{"status": "Hello there"}' --ordering-key="some-key" --attribute "Content-Type=application/json"
The following sections show the difference between a wrapped and unwrapped message.
Wrapped message
The following example shows a standard Pub/Sub wrapped message. In this case, payloading unwrapping isn't enabled.
Publish | Push Endpoint Receives |
---|---|
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/..." } |
Unwrapped message with write metadata disabled
The following example shows an unwrapped message with the write metadata option
disabled. In this case, the x-goog-pubsub-*
headers and message attributes
aren't included.
Publish | Push Endpoint Receives |
---|---|
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"} |
Unwrapped message with write metadata enabled
The following example shows an unwrapped message with the write metadata option
enabled. In this case, the x-goog-pubsub-*
headers and message attributes
are included.
Publish | Push Endpoint Receives |
---|---|
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"} |
Configure payload unwrapping
You can enable payload unwrapping push delivery for a subscription using the Google Cloud console Subscription Details page, the Google Cloud CLI, or the Client Libraries.
Console
In the Google Cloud console, go to the Subscriptions page.
Click Create subscription.
In the Subscription ID field, enter a name.
For information on how to name a subscription, see Guidelines to name a topic or a subscription.
Select a topic from the drop-down menu. The subscription receives messages from the topic.
For Delivery type, select Push.
To enable payload unwrapping, select Enable payload unwrapping.
(Optional) To preserve metadata of messages in the request header, select Write metadata. You must enable this option to set a Content-Type header for your messages.
Specify an endpoint URL.
Retain all other default values.
Click Create.
gcloud
To configure a subscription with payload unwrapping that includes standard
HTTP headers, run the following gcloud pubsub subscriptions create
command:
gcloud pubsub subscriptions create SUBSCRIPTION \ --topic TOPIC \ --push-endpoint=PUSH_ENDPOINT \ --push-no-wrapper
Replace the following:
SUBSCRIPTION
: the name or ID of your pull subscription.TOPIC
: the ID of the topic.PUSH_ENDPOINT
: the URL to use as the endpoint for this subscription. For example,https://myproject.appspot.com/myhandler
--push-no-wrapper
: delivers the message data directly as the HTTP body.
To configure a subscription with payload unwrapping and control the use of
x-goog-pubsub-*
headers, run following command:
gcloud pubsub subscriptions create SUBSCRIPTION \ --topic TOPIC \ --push-endpoint=PUSH_ENDPOINT \ --push-no-wrapper \ --push-no-wrapper-write-metadata
--push-no-wrapper-write-metadata
: When true, writes the Pub/Sub message metadata tox-goog-pubsub-<KEY>:<VAL>
headers of the HTTP request. Writes the Pub/Sub message attributes to<KEY>:<VAL>
headers of the HTTP request.
Python
Before trying this sample, follow the Python setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Python API reference documentation.
Java
Before trying this sample, follow the Java setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Java API reference documentation.
C++
Before trying this sample, follow the C++ setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub C++ API reference documentation.
Go
Before trying this sample, follow the Go setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Go API reference documentation.
Node.js
Before trying this sample, follow the Node.js setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Node.js API reference documentation.
Node.js
Before trying this sample, follow the Node.js setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Node.js API reference documentation.
Set a content-type header in your message
After enabling payload unwrapping, Pub/Sub doesn't
automatically set a media type header field in your request. If you
don't explicitly set a Content-Type
header field, the web server
processing your request might set a default value of
application/octet-stream
or interpret the request in an unexpected manner.
If you require a Content-Type
header, make sure that you explicitly declare it
at publish time to every individual published message. To do this, you must
first enable Write metadata. This result of enabling Write metadata
is shown in the provided examples.
What's next
- If you're having issues with payload unwrapping, see Troubleshoot payload unwrapping.