SMT로 구독 만들기

이 문서에서는 단일 메시지 변환 (SMT)을 사용하여 Pub/Sub 구독을 만드는 방법을 설명합니다.

구독 SMT를 사용하면 Pub/Sub 내에서 직접 메시지 데이터와 속성을 간편하게 수정할 수 있습니다. 이 기능을 사용하면 메시지가 구독자 클라이언트로 전송되기 전에 데이터 정리, 필터링 또는 형식 변환을 실행할 수 있습니다.

SMT로 구독을 만들려면 Google Cloud 콘솔, Google Cloud CLI, 클라이언트 라이브러리 또는 Pub/Sub API를 사용하면 됩니다.

시작하기 전에

필수 역할 및 권한

SMT로 구독을 만드는 데 필요한 권한을 얻으려면 관리자에게 프로젝트에 대한 Pub/Sub 편집자 (roles/pubsub.editor) IAM 역할을 부여해 달라고 요청하세요. 역할 부여에 대한 자세한 내용은 프로젝트, 폴더, 조직에 대한 액세스 관리를 참조하세요.

이 사전 정의된 역할에는 SMT로 구독을 만드는 데 필요한 권한이 포함되어 있습니다. 필요한 정확한 권한을 보려면 필수 권한 섹션을 펼치세요.

필수 권한

SMT로 구독을 만들려면 다음 권한이 필요합니다.

  • 프로젝트에 구독 만들기 권한을 부여합니다. pubsub.subscriptions.create

커스텀 역할이나 다른 사전 정의된 역할을 사용하여 이 권한을 부여받을 수도 있습니다.

구독 유형에 따라 추가 권한이 필요할 수 있습니다. 정확한 권한 목록을 확인하려면 특정 구독 생성에 관한 문서를 참고하세요. 예를 들어 SMT로 BigQuery 구독을 만드는 경우 BigQuery 구독 만들기 페이지를 참고하세요.

주제와 다른 프로젝트에서 구독을 만드는 경우 주제가 포함된 프로젝트에서 구독이 포함된 프로젝트의 사용자에게 roles/pubsub.subscriber 역할을 부여해야 합니다.

프로젝트 수준 및 개별 리소스 수준에서 액세스 제어를 구성할 수 있습니다.

SMT로 구독 만들기

SMT로 정기 결제를 만들기 전에 정기 결제 속성에 관한 문서를 검토하세요.

다음 샘플에서는 이 사용자 정의 함수 (UDF) SMT를 사용하여 구독을 만들고자 한다고 가정합니다. UDF에 관한 자세한 내용은 UDF 개요를 참고하세요.

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

콘솔

  1. Google Cloud 콘솔에서 Pub/Sub 구독 페이지로 이동합니다.

    구독 페이지로 이동

  2. 구독 만들기를 클릭합니다.

    구독 만들기 페이지가 열립니다.

  3. 구독 ID 필드에 구독 ID를 입력합니다. 구독 이름 지정에 대한 자세한 내용은 이름 지정 가이드라인을 참고하세요.

  4. 변환에서 변환 추가를 클릭합니다.

  5. 함수 이름을 입력합니다. 예를 들면 redactSSN입니다.

  6. 구독과 함께 SMT를 즉시 사용하지 않으려면 변환 사용 중지 옵션을 클릭합니다. 이렇게 하면 SMT가 저장되지만 메시지가 구독을 통해 전송될 때 실행되지는 않습니다.

  7. 새 변환을 입력합니다. 예를 들면 다음과 같습니다.

    function redactSSN(message, metadata) {
      const data = JSON.parse(message.data);
      delete data['ssn'];
      message.data = JSON.stringify(data);
      return message;
    }
  8. Pub/Sub는 SMT를 검증할 수 있는 validate 함수를 제공합니다. 검증을 클릭하여 변환을 검증합니다.

  9. 다른 변환을 추가하려면 변환 추가를 클릭합니다.

  10. 모든 SMT를 특정 순서로 정렬하려면 위쪽 및 아래쪽 화살표를 사용하면 됩니다. SMT를 삭제하려면 삭제 버튼을 클릭합니다.
  11. Pub/Sub는 샘플 메시지에서 SMT 실행 결과를 확인할 수 있는 테스트 함수를 제공합니다. SMT를 테스트하려면 변환 테스트를 클릭합니다.

  12. Test transform 창에서 테스트할 함수를 선택합니다.

  13. 메시지 입력 창에 샘플 메시지를 입력합니다.

  14. 메시지 속성을 추가하려면 속성 추가를 클릭하고 키-값 쌍을 하나 이상 입력합니다.

  15. 테스트를 클릭합니다. 메시지에 SMT를 적용한 결과가 표시됩니다.

  16. 창을 닫아 샘플 메시지에서 SMT 테스트를 중지합니다.

  17. 만들기를 클릭하여 구독을 만듭니다.

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. Pub/Sub는 SMT를 검증할 수 있는 validate 함수를 제공합니다. gcloud pubsub message-transforms validate 명령어를 실행합니다.

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

    다음을 바꿉니다.

    • TRANSFORM_FILE: 단일 SMT가 포함된 YAML 또는 JSON 파일의 경로입니다.

      다음은 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. Pub/Sub는 샘플 메시지에서 하나 이상의 SMT를 실행한 결과를 확인할 수 있는 테스트 함수를 제공합니다. gcloud pubsub message-transforms test 명령어를 실행합니다.

    gcloud pubsub message-transforms test --message-transforms-file=TRANSFORMS_FILE

    다음을 바꿉니다.

    • TRANSFORMS_FILE: 하나 이상의 SMT가 포함된 YAML 또는 JSON 파일의 경로입니다.

      다음은 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

  4. 구독을 만들려면 gcloud pubsub subscriptions create 명령어를 실행합니다.

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

    다음을 바꿉니다.

    • SUBSCRIPTION_ID: 만들려는 구독의 ID 또는 이름입니다. 구독 이름 지정 방법에 관한 가이드라인은 리소스 이름을 참고하세요. 구독 이름은 변경할 수 없습니다.

    • TOPIC_NAME: 구독할 주제의 이름으로, projects/PROJECT_ID/topics/TOPIC_ID 형식입니다.

    • TRANSFORMS_FILE: 하나 이상의 SMT가 포함된 YAML 또는 JSON 파일의 경로입니다.

      다음은 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

이 샘플을 사용해 보기 전에 Pub/Sub 빠른 시작: 클라이언트 라이브러리 사용Java 설정 안내를 따르세요. 자세한 내용은 Pub/Sub Java API 참고 문서를 확인하세요.

Pub/Sub에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

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

이 샘플을 사용해 보기 전에 Pub/Sub 빠른 시작: 클라이언트 라이브러리 사용Python 설정 안내를 따르세요. 자세한 내용은 Pub/Sub Python API 참고 문서를 확인하세요.

Pub/Sub에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

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

이 샘플을 사용해 보기 전에 Pub/Sub 빠른 시작: 클라이언트 라이브러리 사용Go 설정 안내를 따르세요. 자세한 내용은 Pub/Sub Go API 참고 문서를 확인하세요.

Pub/Sub에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

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

SMT가 다른 구독 기능과 상호작용하는 방식

구독에서 SMT와 Pub/Sub의 기본 제공 필터를 모두 사용하는 경우 필터가 SMT 전에 적용됩니다. 이로 인한 의미는 다음과 같습니다.

  • SMT가 메시지 속성을 변경하면 Pub/Sub 필터가 새 속성 집합에 적용되지 않습니다.
  • Pub/Sub 필터에 의해 필터링된 메시지에는 SMT가 적용되지 않습니다.

SMT에서 메시지를 필터링하는 경우 구독 백로그 모니터링에 미치는 영향을 고려하세요. 구독을 Dataflow 파이프라인에 제공하는 경우 SMT를 사용하여 메시지를 필터링하지 마세요. Dataflow의 자동 확장이 중단됩니다.

다음 단계