JavaScript 使用者定義函式 (UDF) 是一種單一訊息轉換 (SMT)。使用者定義函式提供彈性的方式,可在 Pub/Sub 中實作自訂轉換邏輯,類似於 BigQuery JavaScript 使用者定義函式。
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
引數:包含 Pub/Sub 訊息不可變更中繼資料的 JavaScript 物件:
輸出內容
如要轉換訊息,請編輯
message.data
和message.attributes
的內容,然後傳回經過變更的message
物件。如要篩選訊息,請傳回
null
。
使用者定義函式如何轉換訊息
在郵件上執行 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 毫秒
- 僅支援 ECMAScript 標準內建函式
- 不呼叫外部 API
- 未匯入外部程式庫
UDF 範例
以下列舉一些發布及訂閱的 UDF 範例。
函式:將星期幾的整數轉換為對應的字串
將下列 UDF 新增至主題或訂閱項目時,系統會在發布或傳送訊息期間進行下列變更:
Pub/Sub 會將函式套用至訊息。如果訊息沒有 JSON 酬載,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;
}