Criar uma assinatura com SMTs

Neste documento, explicamos como criar uma assinatura do Pub/Sub com transformações de mensagem única (SMTs, na sigla em inglês).

As SMTs de assinatura permitem modificações leves nos dados e atributos de mensagens diretamente no Pub/Sub. Esse recurso permite a limpeza, filtragem ou conversão de formato de dados antes que as mensagens sejam entregues a um cliente assinante.

Para criar uma assinatura com SMTs, use o console Google Cloud , a Google Cloud CLI, a biblioteca de cliente ou a API Pub/Sub.

Antes de começar

Papéis e permissões necessárias

Para receber as permissões necessárias para criar uma assinatura com SMTs, peça ao administrador para conceder a você o papel do IAM de Editor do Pub/Sub (roles/pubsub.editor) no seu projeto. Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

Esse papel predefinido contém as permissões necessárias para criar uma assinatura com SMTs. Para conferir as permissões exatas necessárias, expanda a seção Permissões necessárias:

Permissões necessárias

As seguintes permissões são necessárias para criar uma assinatura com SMTs:

  • Conceda a permissão para criar uma assinatura no projeto: pubsub.subscriptions.create

Essas permissões também podem ser concedidas com funções personalizadas ou outros papéis predefinidos.

Dependendo do tipo de assinatura, talvez sejam necessárias mais permissões. Para saber a lista exata de permissões, consulte o documento que discute a criação da assinatura específica. Por exemplo, se você estiver criando uma assinatura do BigQuery com SMTs, consulte a página Criar assinaturas do BigQuery.

Se você criar uma assinatura em um projeto diferente do tópico, será necessário conceder o papel roles/pubsub.subscriber ao principal do projeto que contém a assinatura no projeto que contém o tópico.

É possível configurar o controle de acesso no nível do projeto e no nível do recurso individual.

Criar uma assinatura com SMTs

Antes de criar uma assinatura com SMTs, consulte a documentação sobre Propriedades de uma assinatura.

Os exemplos a seguir pressupõem que você quer criar uma assinatura com essa SMT de função definida pelo usuário (UDF). Para mais informações sobre UDFs, consulte a visão geral das UDFs.

function redactSSN(message, metadata) {
  const data = JSON.parse(message.data);
  delete data['ssn'];
  message.data = JSON.stringify(data);
  return message;
}

Console

  1. No console Google Cloud , acesse a página Assinaturas do Pub/Sub.

    Acessar "Assinaturas"

  2. Clique em Criar assinatura.

    A página Criar assinatura é aberta.

  3. No campo ID da assinatura, insira um ID para a assinatura. Para mais informações sobre como nomear assinaturas, consulte as diretrizes de nomenclatura.

  4. Em Transformações, clique em Adicionar uma transformação.

  5. Insira um nome de função. Por exemplo, redactSSN.

  6. Se você não quiser usar a SMT com sua assinatura imediatamente, clique na opção Desativar transformação. Isso ainda vai salvar a SMT, mas ela não será executada conforme as mensagens fluem pela sua assinatura.

  7. Insira uma nova transformação. Exemplo:

    function redactSSN(message, metadata) {
      const data = JSON.parse(message.data);
      delete data['ssn'];
      message.data = JSON.stringify(data);
      return message;
    }
  8. O Pub/Sub oferece uma função de validação que permite validar uma SMT. Clique em Validar para validar a transformação.

  9. Se quiser adicionar outra transformação, clique em Adicionar uma transformação.

  10. Para organizar todas as SMTs em uma ordem específica, use as setas para cima e para baixo. Para remover um SMT, clique no botão de exclusão.
  11. O Pub/Sub oferece uma função de teste que permite verificar o resultado da execução do SMT em uma mensagem de amostra. Para testar as SMTs, clique em Testar transformação.

  12. Na janela Test transform, selecione a função que você quer testar.

  13. Na janela Mensagem de entrada, digite uma mensagem de exemplo.

  14. Se quiser adicionar atributos de mensagem, clique em Adicionar um atributo e insira um ou mais pares de chave-valor.

  15. Clique em Testar. O resultado da aplicação das SMTs na mensagem é exibido.

  16. Feche a janela para interromper o teste de SMTs em mensagens de amostra.

  17. Clique em Criar para criar a assinatura.

gcloud

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. O Pub/Sub oferece uma função de validação que permite validar um SMT. Execute o comando gcloud pubsub message-transforms validate:

    gcloud pubsub message-transforms validate --message-transform-file=TRANSFORM_FILE

    Substitua:

    • TRANSFORM_FILE: o caminho para o arquivo YAML ou JSON que contém um único SMT.

      Confira um exemplo de arquivo de transformação YAML:

      javascriptUdf:
          code: >
              function redactSSN(message, metadata) {
                const data = JSON.parse(message.data);
                delete data['ssn'];
                message.data = JSON.stringify(data);
                return message;
              }
          functionName: redactSSN

  3. O Pub/Sub oferece uma função de teste que permite verificar o resultado da execução de um ou mais SMTs em uma mensagem de amostra. Execute o comando gcloud pubsub message-transforms test:

    gcloud pubsub message-transforms test --message-transforms-file=TRANSFORMS_FILE --message=MESSAGE --attributes=ATTRIBUTES

    Substitua:

    • TRANSFORMS_FILE: o caminho para o arquivo YAML ou JSON que contém um ou mais SMTs.

      Confira um exemplo de arquivo de transformações YAML:

      - javascriptUdf:
          code: >
              function redactSSN(message, metadata) {
                const data = JSON.parse(message.data);
                delete data['ssn'];
                message.data = JSON.stringify(data);
                return message;
              }
          functionName: redactSSN

    • MESSAGE: corpo da mensagem para testar os SMTs.

    • ATTRIBUTES: atributos de mensagem para testar os SMTs.

  4. Para criar a assinatura, execute o comando gcloud pubsub subscriptions create:

    gcloud pubsub subscriptions create SUBSCRIPTION_ID \
        --topic=TOPIC_NAME \
        --message-transforms-file=TRANSFORMS_FILE

    Substitua:

    • SUBSCRIPTION_ID: o ID ou nome da assinatura que você quer criar. Para diretrizes sobre como nomear uma assinatura, consulte Nomes de recursos. O nome de uma assinatura é imutável.

    • TOPIC_NAME: o nome do tópico a ser assinado, no formato projects/PROJECT_ID/topics/TOPIC_ID.

    • TRANSFORMS_FILE: o caminho para o arquivo YAML ou JSON que contém um ou mais SMTs.

      Confira um exemplo de arquivo de transformações YAML:

      - javascriptUdf:
          code: >
              function redactSSN(message, metadata) {
                const data = JSON.parse(message.data);
                delete data['ssn'];
                message.data = JSON.stringify(data);
                return message;
              }
          functionName: redactSSN

Java

Antes de testar esta amostra, siga as instruções de configuração do Java no Guia de início rápido do Pub/Sub: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub Java.

Para autenticar no Pub/Sub, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

import com.google.cloud.pubsub.v1.SubscriptionAdminClient;
import com.google.pubsub.v1.JavaScriptUDF;
import com.google.pubsub.v1.MessageTransform;
import com.google.pubsub.v1.ProjectSubscriptionName;
import com.google.pubsub.v1.ProjectTopicName;
import com.google.pubsub.v1.Subscription;
import java.io.IOException;

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

    createSubscriptionWithSmtExample(projectId, topicId, subscriptionId);
  }

  public static void createSubscriptionWithSmtExample(
      String projectId, String topicId, String subscriptionId) throws IOException {

    // UDF that removes the 'ssn' field, if present
    String code =
        "function redactSSN(message, metadata) {"
            + "  const data = JSON.parse(message.data);"
            + "  delete data['ssn'];"
            + "  message.data = JSON.stringify(data);"
            + "  return message;"
            + "}";
    String functionName = "redactSSN";

    JavaScriptUDF udf =
        JavaScriptUDF.newBuilder().setCode(code).setFunctionName(functionName).build();
    MessageTransform transform = MessageTransform.newBuilder().setJavascriptUdf(udf).build();

    try (SubscriptionAdminClient subscriptionAdminClient = SubscriptionAdminClient.create()) {

      ProjectTopicName topicName = ProjectTopicName.of(projectId, topicId);
      ProjectSubscriptionName subscriptionName =
          ProjectSubscriptionName.of(projectId, subscriptionId);

      Subscription subscription =
          subscriptionAdminClient.createSubscription(
              Subscription.newBuilder()
                  .setName(subscriptionName.toString())
                  .setTopic(topicName.toString())
                  // Add the UDF message transform
                  .addMessageTransforms(transform)
                  .build());

      System.out.println("Created subscription with SMT: " + subscription.getAllFields());
    }
  }
}

Python

Antes de testar esta amostra, siga as instruções de configuração do Python no Guia de início rápido do Pub/Sub: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub Python.

Para autenticar no Pub/Sub, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

from google.cloud import pubsub_v1
from google.pubsub_v1.types import JavaScriptUDF, MessageTransform

# TODO(developer): Choose an existing topic.
# project_id = "your-project-id"
# topic_id = "your-topic-id"
# subscription_id = "your-subscription-id"

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)

code = """function redactSSN(message, metadata) {
            const data = JSON.parse(message.data);
            delete data['ssn'];
            message.data = JSON.stringify(data);
            return message;
            }"""
udf = JavaScriptUDF(code=code, function_name="redactSSN")
transforms = [MessageTransform(javascript_udf=udf)]

with subscriber:
    subscription = subscriber.create_subscription(
        request={
            "name": subscription_path,
            "topic": topic_path,
            "message_transforms": transforms,
        }
    )
    print(f"Created subscription with SMT: {subscription}")

Go

Antes de testar esta amostra, siga as instruções de configuração do Go no Guia de início rápido do Pub/Sub: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub Go.

Para autenticar no Pub/Sub, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

// Copyright 2025 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
//
//     https://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 subscriptions

import (
	"context"
	"fmt"
	"io"

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

// createSubscriptionWithSMT creates a subscription with a single message transform function applied.
func createSubscriptionWithSMT(w io.Writer, projectID, subID string, topic *pubsub.Topic) error {
	// projectID := "my-project-id"
	// subID := "my-sub"
	// topic of type https://godoc.org/cloud.google.com/go/pubsub#Topic
	ctx := context.Background()
	client, err := pubsub.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("pubsub.NewClient: %w", err)
	}
	defer client.Close()

	code := `function redactSSN(message, metadata) {
			const data = JSON.parse(message.data);
			delete data['ssn'];
			message.data = JSON.stringify(data);
			return message;
		}`
	transform := pubsub.MessageTransform{
		Transform: pubsub.JavaScriptUDF{
			FunctionName: "redactSSN",
			Code:         code,
		},
	}
	cfg := pubsub.SubscriptionConfig{
		Topic:             topic,
		MessageTransforms: []pubsub.MessageTransform{transform},
	}
	sub, err := client.CreateSubscription(ctx, subID, cfg)
	if err != nil {
		return fmt.Errorf("CreateSubscription: %w", err)
	}
	fmt.Fprintf(w, "Created subscription with message transform: %v\n", sub)
	return nil
}

Como as SMTs interagem com outros recursos de assinatura

Se a assinatura usa SMTs e filtros integrados do Pub/Sub, o filtro é aplicado antes da SMT. Isso tem as seguintes implicações:

  • Se o SMT alterar os atributos da mensagem, o filtro do Pub/Sub não será aplicado ao novo conjunto de atributos.
  • Sua SMT não será aplicada a mensagens filtradas pelo filtro do Pub/Sub.

Se o SMT filtrar mensagens, fique atento ao impacto no monitoramento do backlog de assinaturas. Se você alimentar a assinatura em um pipeline do Dataflow, não filtre as mensagens usando o SMT, porque isso interrompe o escalonamento automático do Dataflow.

A seguir