JavaScript 使用者定義函式 (UDF) 是一種單一訊息轉換 (SMT)。UDF 可提供靈活的方式,在 Pub/Sub 中實作自訂轉換邏輯,類似於 BigQuery JavaScript UDF。
UDF 會接受單一訊息做為輸入內容,對輸入內容執行定義的動作,並傳回程序的結果。
UDF 具有下列重要屬性:
函式名稱:Pub/Sub 套用至訊息的提供程式碼中 JavaScript 函式名稱。
程式碼:定義轉換邏輯的 JavaScript 程式碼。此程式碼必須包含具有下列簽章的函式:
/** * 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
引數:JavaScript 物件,其中包含 Pub/Sub 訊息的不可變更中繼資料:
輸出內容
如要轉換訊息,請編輯
message.data
和message.attributes
的內容,並傳回經過修改的message
物件。如要篩選訊息,請傳回
null
。
UDF 如何轉換訊息
在郵件上執行 UDF 的結果可能為下列任一項目:
UDF 會轉換訊息。
UDF 會傳回
null
。主題 SMT:Pub/Sub 會傳回成功訊息給發布者,並在篩選後的訊息回應中加入訊息 ID。Pub/Sub 不會儲存訊息,也不會將訊息傳送給任何訂閱者。
訂閱 SMT:Pub/Sub 會確認訊息已送達,但不會將訊息傳送給訂閱者。
UDF 會擲回錯誤。
主題 SMT:Pub/Sub 會將錯誤傳回給發布端,且不會發布任何訊息。
訂閱 SMT:Pub/Sub 已否認訊息。
資源限制
Pub/Sub 會對 UDF 設下資源限制,確保轉換作業的效率。限制包括:
- 每個 UDF 的程式碼大小上限為 20 KB
- 每則訊息的執行時間上限為 500 毫秒
- 不呼叫外部 API
- 不匯入外部程式庫
UDF 範例
以下是發布和訂閱的 UDF 範例。
函式:將星期幾整數轉換為對應的字串
將下列 UDF 新增至主題或訂閱項目後,系統會在訊息發布或傳送期間進行下列變更:
Pub/Sub 會將函式套用至訊息。如果訊息沒有 JSON 酬載,UDF 就會擲回錯誤。
UDF 會尋找名為
dayOfWeek
的欄位,如果這個欄位的值是介於 0 到 6 之間的數字,就會轉換為對應的一週天數,例如Monday
。如果欄位不存在,或數字不在 0 到 6 的範圍內,程式碼會將dayOfWeek
欄位設為Unknown
。UDF 會將已修改的酬載序列化,並將其傳回至訊息。
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 新增至主題或訂閱項目後,系統會在訊息發布或傳送期間進行下列變更:
Pub/Sub 會將函式套用至訊息。如果訊息沒有 JSON 酬載,則 UDF 會擲回錯誤。
UDF 會從訊息酬載中移除欄位
ssn
(如果存在的話)。UDF 會將已修改的酬載序列化,並將其傳回至訊息。
Pub/Sub 會將更新後的訊息傳遞至管道中的下一個步驟。
function redactSSN(message, metadata) {
const data = JSON.parse(message.data);
delete data['ssn'];
message.data = JSON.stringify(data);
return message;
}
功能:篩除特定訊息並自動回覆
將下列 UDF 新增至主題或訂閱項目後,系統會在訊息發布或傳送期間進行下列變更:
Pub/Sub 會將函式套用至訊息。如果訊息沒有 JSON 酬載,UDF 就會擲回錯誤。
UDF 會檢查酬載是否包含名為
region
的欄位。如果
region
欄位的值不是US
,函式會傳回空值,導致 Pub/Sub 篩除訊息。如果
region
欄位的值為US
,Pub/Sub 會將原始訊息傳遞至管道中的下一個步驟。
function filterForUSRegion(message, metadata) {
const data = JSON.parse(message.data);
if (data["region"] !== "US") {
return null;
}
return message;
}
函式:驗證訊息內容,確保金額不超過 100
將下列 UDF 新增至主題或訂閱項目後,系統會在訊息發布或傳送期間進行下列變更:
Pub/Sub 會將函式套用至訊息。如果訊息沒有 JSON 酬載,UDF 就會擲回錯誤。
UDF 會檢查訊息是否包含名為
amount
的欄位。如果
amount
欄位的值大於100
,函式就會擲回錯誤。如果
amount
欄位的值不大於100
,函式會傳回原始訊息。接著,Pub/Sub 會將訊息標示為失敗,或將原始訊息傳遞至管道中的下一個步驟。
function validateAmount(message, metadata) {
const data = JSON.parse(message.data);
if (data["amount"] > 100) {
throw new Error("Amount is invalid");
}
return message;
}