사용자 정의 함수 (UDF) 개요

JavaScript 사용자 정의 함수 (UDF)는 단일 메시지 변환 (SMT)의 한 유형입니다. UDF는 BigQuery JavaScript UDF와 마찬가지로 Pub/Sub 내에서 맞춤 변환 로직을 구현하는 유연한 방법을 제공합니다.

UDF는 단일 메시지를 입력으로 받아 입력에 정의된 작업을 실행하고 프로세스의 결과를 반환합니다.

UDF에는 다음과 같은 주요 속성이 있습니다.

  • 코드: 변환 로직을 정의하는 JavaScript 코드입니다.

  • 함수 이름: 제공된 코드 내에서 Pub/Sub이 메시지에 적용되는 JavaScript 함수의 이름입니다.

JavaScript 함수 만들기

UDF 코드에는 다음 서명이 있는 함수가 포함되어야 합니다.

  /**
  * Transforms a Pub/Sub message.
  * @return {(Object<string, (string | Object<string, string>)>|* null)} - To
  * filter a message, return `null`. To transform a message, return a map with
  * the following keys:
  *   - (required) 'data' : {string}
  *   - (optional) 'attributes' : {Object<string, string>}
  * Returning empty `attributes` will remove all attributes from the message.
  *
  * @param  {(Object<string, (string | Object<string, string>)>} - Pub/Sub
  * message. Keys:
  *   - (required) 'data' : {string}
  *   - (required) 'attributes' : {Object<string, string>}
  *
  * @param  {Object<string, any>} metadata - Pub/Sub message metadata.
  * Keys:
  *   - (optional) 'message_id'  : {string}
  *   - (optional) 'publish_time': {string} YYYY-MM-DDTHH:MM:SSZ format
  *   - (optional) 'ordering_key': {string}
  */
  function <function_name>(message, metadata) {
    // Perform custom transformation logic
    return message; // to filter a message instead, return `null`
  }

입력

이 함수는 다음 입력을 사용합니다.

  • message 인수: Pub/Sub 메시지를 나타내는 JavaScript 객체입니다. 다음 속성이 포함되어 있습니다.

    • data: (String, 필수) 메시지 페이로드입니다.

    • attributes: (Object<String, String>, 선택사항) 메시지 속성을 나타내는 키-값 쌍의 맵입니다.

  • metadata 인수: Pub/Sub 메시지에 관한 변경 불가능한 메타데이터를 포함하는 JavaScript 객체입니다.

    • message_id: (String, 선택사항) 메시지의 고유 ID입니다.

    • publish_time: (String, 선택사항) 메시지의 게시 시간입니다. RFC 3339 형식 (YYYY-MM-DDTHH:mm:ssZ)입니다.

    • ordering_key: (String, 선택사항) 해당되는 경우 메시지의 순서 키입니다.

출력

함수는 다음 중 하나를 반환해야 합니다.

  • 메시지를 변환하려면 message.data 및 message.attributes의 콘텐츠를 수정하고 변경된 message 객체를 반환합니다.

  • 메시지를 필터링하려면 null를 반환합니다.

입력 / 출력 요구사항

  • UDF가 메시지 페이로드를 변환하는 경우 페이로드 입력과 출력은 UTF-8로 인코딩된 문자열이어야 합니다.
  • UDF가 메시지 페이로드를 변환하지 않으면 페이로드는 모든 인코딩을 사용할 수 있습니다.
  • 속성 키-값 쌍은 UTF-8로 인코딩된 문자열이어야 합니다.

UDF가 메시지를 변환하는 방식

메시지에서 UDF를 실행한 결과는 다음 중 하나일 수 있습니다.

  • UDF가 메시지를 변환합니다.

  • UDF는 null를 반환합니다.

    • 주제 SMT: Pub/Sub는 게시자에게 성공을 반환하고 필터링된 메시지의 응답에 메시지 ID를 포함합니다. Pub/Sub는 메시지를 저장하거나 구독자에게 전송하지 않습니다.

    • 구독 SMT: Pub/Sub는 구독자에게 메시지를 전송하지 않고 메시지 전송을 확인합니다.

  • UDF에서 오류가 발생합니다.

    • 주제 SMT: Pub/Sub는 게시자에게 오류를 반환하고 메시지를 게시하지 않습니다.

    • 구독 SMT: Pub/Sub에서 메시지를 부정적으로 확인합니다.

UDF SMT 만들기

SMT는 Pub/Sub 주제 또는 구독에서 구성할 수 있습니다.

  • 주제 SMT는 Pub/Sub가 메시지를 저장하기 전에 실행되며 결과는 모든 구독자가 사용할 수 있습니다.
  • 구독 SMT는 메시지가 전송되기 전에 실행되며 결과는 해당 구독에서만 사용할 수 있습니다.

콘솔

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

    주제로 이동

  2. 주제 또는 구독을 만듭니다.

    • 주제를 만들려면 주제 만들기를 클릭합니다. 주제 만들기 페이지가 열립니다.

    • 구독을 만들려면 다음 단계를 따르세요.

      1. 구독을 원하는 주제의 이름을 클릭합니다.

      2. 구독 만들기를 클릭합니다. 주제에 구독 추가 페이지가 열립니다.

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

  4. 변환 유형으로 JavaScript UDF를 선택합니다.

  5. 선택사항: 다음과 같이 Gemini Enterprise를 사용하여 UDF의 코드를 생성할 수 있습니다.

    1. AI로 생성을 클릭합니다.

    2. 텍스트 필드에 함수가 수행해야 하는 작업을 설명합니다. 예를 들어 '현재 시간으로 processed_at 속성 추가'를 입력합니다.

    3. 제출을 클릭합니다. 생성된 코드는 코드 설명과 함께 AI로 생성 창에 표시됩니다.

    4. 코드의 정확성을 검사합니다. 설명을 수정하고 코드를 다시 생성해야 할 수도 있습니다.

    5. 생성된 코드를 사용하려면 가져오기를 클릭합니다.

  6. 함수 이름 필드에 SMT가 호출하는 JavaScript 함수의 이름을 입력합니다. 예: redactSSN

    Gemini Enterprise를 사용하여 코드를 생성한 경우 이 필드는 이미 입력되어 있습니다.

  7. 텍스트 영역에 UDF 코드를 입력합니다. 예:

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

    코드에는 이름이 함수 이름 필드와 일치하는 함수가 포함되어야 합니다.

    Gemini Enterprise를 사용하여 코드를 생성한 경우 이 필드는 이미 입력되어 있습니다.

  8. SMT가 즉시 활성화되지 않도록 하려면 변환 사용 중지를 선택합니다. 이 옵션을 선택하면 SMT가 주제와 함께 생성되지만 수신 메일에서는 실행되지 않습니다. 주제가 생성된 후 주제를 수정하여 SMT를 사용 설정할 수 있습니다.

  9. 주제 또는 구독을 만들려면 만들기를 클릭합니다.

gcloud

정의 파일 만들기

UDF SMT를 정의하는 YAML 또는 JSON 파일을 만듭니다.

YAML

- javascriptUdf:
    code: { FUNCTION_CODE }
    functionName: FUNCTION_NAME

JSON

{
  "javascriptUdf": {
    "code": {
      FUNCTION_CODE
    }
    "functionName": FUNCTION_NAME
  }
}

다음을 바꿉니다.

  • FUNCTION_CODE: UDF의 JavaScript 코드입니다. 코드에는 이름이 functionName 필드와 일치하는 함수가 포함되어야 합니다. 예:

    function redactSSN(message, metadata) {
      const data = JSON.parse(message.data);
      delete data['ssn'];
      message.data = JSON.stringify(data);
      return message;
    }
    
  • FUNCTION_NAME: SMT가 호출하는 JavaScript 함수의 이름입니다. 예: redactSSN

주제 또는 구독 만들기

주제를 만들려면 gcloud pubsub topics create 명령어를 실행합니다.

gcloud pubsub topics create TOPIC_ID \
  --message-transforms-file=TRANSFORMS_FILE

다음을 바꿉니다.

  • TOPIC_ID: 만들려는 주제의 ID 또는 이름입니다.
  • TRANSFORMS_FILE: 정의 파일의 경로입니다.

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

gcloud pubsub subscriptions create SUBSCRIPTION_ID \
  --topic=projects/PROJECT_ID/topics/TOPIC_ID \
  --message-transforms-file=TRANSFORMS_FILE

다음을 바꿉니다.

  • SUBSCRIPTION_ID: 생성할 구독의 ID 또는 이름입니다.

  • PROJECT_ID: 주제가 포함된 프로젝트의 ID입니다.

  • TOPIC_ID: 구독할 주제의 ID입니다.

  • TRANSFORMS_FILE: 정의 파일의 경로입니다.

선택적으로 SMT를 만들기 전에 검증하고 테스트할 수 있습니다. 자세한 내용은 다음 페이지를 참고하세요.

제한사항

Pub/Sub는 효율적인 변환 작업을 위해 UDF에 리소스 한도를 적용합니다. 제한사항은 다음과 같습니다.

  • UDF당 최대 20KB의 코드
  • 메시지당 최대 500ms의 실행 시간
  • ECMAScript 표준 내장만 지원
  • 외부 API 호출 없음
  • 외부 라이브러리 가져오기 없음

샘플 UDF

다음은 게시 및 구독을 위한 샘플 UDF입니다. UDF 라이브러리에서 추가 샘플을 확인할 수 있습니다.

함수: 요일 정수를 해당 문자열로 변환

다음 UDF를 주제 또는 구독에 추가하면 메시지 게시 또는 전송 중에 다음과 같은 변경사항이 발생합니다.

  1. Pub/Sub가 메시지에 함수를 적용합니다. 메시지에 JSON 페이로드가 없으면 UDF에서 오류가 발생합니다.

  2. UDF는 dayOfWeek이라는 필드를 찾고 이 필드의 값이 0~6 사이의 숫자이면 Monday과 같은 해당 요일로 변환합니다. 필드가 없거나 숫자가 0~6 범위에 없으면 코드는 dayOfWeek 필드를 Unknown로 설정합니다.

  3. UDF는 수정된 페이로드를 메시지로 다시 직렬화합니다.

  4. Pub/Sub은 업데이트된 메시지를 파이프라인의 다음 단계로 전달합니다.

function intToString(message, metadata) {
  const data = JSON.parse(message.data);
  switch(`data["dayOfWeek"]`) {
    case 0:
      data["dayOfWeek"] = "Sunday";
      break;
    case 1:
      data["dayOfWeek"] = "Monday";
      break;
    case 2:
      data["dayOfWeek"] = "Tuesday";
      break;
    case 3:
      data["dayOfWeek"] = "Wednesday";
      break;
    case 4:
      data["dayOfWeek"] = "Thursday";
      break;
    case 5:
      data["dayOfWeek"] = "Friday";
      break;
    case 6:
      data["dayOfWeek"] = "Saturday";
      break;
    default:
      data["dayOfWeek"] = "Unknown";
  }
  message.data = JSON.stringify(data);
  return message;
}

기능: 주민등록번호 수정

다음 UDF를 주제 또는 구독에 추가하면 메시지 게시 또는 전송 중에 다음과 같은 변경사항이 발생합니다.

  1. Pub/Sub가 메시지에 함수를 적용합니다. 메시지에 JSON 페이로드가 없으면 UDF에서 오류가 발생합니다.

  2. UDF는 메시지 페이로드에서 ssn 필드를 삭제합니다 (있는 경우).

  3. UDF는 수정된 페이로드를 메시지로 다시 직렬화합니다.

  4. Pub/Sub은 업데이트된 메시지를 파이프라인의 다음 단계로 전달합니다.

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

기능: 특정 메시지 필터링 및 자동 확인

다음 UDF를 주제 또는 구독에 추가하면 메시지 게시 또는 전송 중에 다음과 같은 변경사항이 발생합니다.

  1. Pub/Sub가 메시지에 함수를 적용합니다. 메시지에 JSON 페이로드가 없으면 UDF에서 오류가 발생합니다.

  2. UDF는 페이로드에 region라는 필드가 포함되어 있는지 확인합니다.

  3. region 필드 값이 US이 아니면 함수는 null을 반환하여 Pub/Sub가 메시지를 필터링하도록 합니다.

  4. region 필드 값이 US인 경우 Pub/Sub은 파이프라인의 다음 단계로 원래 메시지를 전달합니다.

function filterForUSRegion(message, metadata) {
  const data = JSON.parse(message.data);
  if (data["region"] !== "US") {
    return null;
  }
  return message;
}

기능: 금액이 100을 초과하지 않도록 메시지 콘텐츠 유효성 검사

다음 UDF를 주제 또는 구독에 추가하면 메시지 게시 또는 전송 중에 다음과 같은 변경사항이 발생합니다.

  1. Pub/Sub가 메시지에 함수를 적용합니다. 메시지에 JSON 페이로드가 없으면 UDF에서 오류가 발생합니다.

  2. UDF는 메시지에 amount이라는 필드가 포함되어 있는지 확인합니다.

  3. amount 필드의 값이 100보다 크면 함수에서 오류가 발생합니다.

  4. amount 필드의 값이 100보다 크지 않으면 함수는 원래 메시지를 반환합니다.

  5. 그러면 Pub/Sub가 메시지를 실패로 표시하거나 파이프라인의 다음 단계로 원래 메시지를 전달합니다.

function validateAmount(message, metadata) {
  const data = JSON.parse(message.data);
  if (data["amount"] > 100) {
    throw new Error("Amount is invalid");
  }
  return message;
}

다음 단계