您可以使用 CEL 編寫轉換運算式,轉換 CloudEvents 資料。詳情請參閱「轉換收到的事件」。
以下列舉一些常見用途和範例,說明如何編寫 CEL 運算式來轉換事件資料。
標準用途
以下列舉幾個轉換事件資料的標準用途。
資料正規化
您需要將事件訊息中的巢狀資料結構扁平化,以便下游服務更輕鬆地處理。
- 情境:
假設有下列 CloudEvents 資料:
{ "data": { "orderId": "12345", "customer": { "firstName": "Alex", "lastName": "Taylor", "address": { "street": "1800 Amphibious Blvd.", "city": "Mountain View" } } } }
您想編寫 CEL 運算式,產生下列輸出內容:
{ "data": { "orderId": "12345", "customerFirstName": "Alex", "customerLastName": "Taylor", "customerStreet": "1800 Amphibious Blvd.", "customerCity": "Mountain View" } }
- 解決方案 1:
手動設定輸出資料格式。這樣一來,您就能列出欄位名稱,並只挑選輸出內容中需要的元素。如果輸入內容可預測,且欄位數量不多,這就是合理的方法。
setField
函式會新增或取代具有指定鍵的事件欄位。例如:message.setField("data", { "orderId": message.data.orderId, "customerFirstName": message.data.customer.firstName, "customerLastName": message.data.customer.lastName, "customerStreet": message.data.customer.address.street, "customerCity": message.data.customer.address.city, })
- 解決方案 2:
在運算式中使用函式。
setField
函式會新增或取代具有指定鍵的事件欄位。denormalize
函式會將深層結構扁平化為鍵/值組合清單。欄位名稱會使用半形句號 (.
) 做為分隔符,區隔結構階層。例如:message.setField("data", message.data.denormalize())
這會產生下列輸出內容,與預期酬載略有不同。不過,這項功能有許多優點,包括可縮短 CEL 運算式,且適用於任何輸入內容,並會自動納入任意數量的傳入欄位。
{ "data": { "orderId": "12345", "customer.firstName": "Alex", "customer.lastName": "Taylor", "customer.address.street": "1800 Amphibious Blvd.", "customer.address.city": "Mountain View" } }
資料遮蓋
您必須先遮蓋事件酬載中的私密資料,再傳送至安全性較低的環境。
- 情境:
假設有下列 CloudEvents 資料:
{ "data": { "userId": "user123", "email": "alex@example.com", "creditCardNumber": "1234-5678-9012-3456" } }
您想編寫 CEL 運算式,產生下列輸出內容:
{ "data": { "userId": "user123", "email": "a***@example.com", "creditCardNumber": "xxxx-xxxx-xxxx-3456" } }
- 解決方法:
使用運算式遮蓋電子郵件地址和信用卡號碼等機密資訊。
setField
函式會新增或取代具有指定鍵的事件欄位。extract
規則運算式函式遵循 RE2 語法。 例如:message .setField("data.email", re.extract(message.data.email, "(^.).*@(.*)", "\\1***@\\2")) .setField("data.creditCardNumber", re.extract(message.data.creditCardNumber, "(\\d{4})\\D*$", "xxxx-xxxx-xxxx-\\1"))
資料遮蓋
您需要根據特定條件,從事件酬載中移除特定欄位。
- 情境:
假設有下列 CloudEvents 資料:
{ "data": { "orderId": "12345", "customerType": "gold", "discountCode": "VIP" } }
您想編寫 CEL 運算式,產生下列輸出內容:
{ { "orderId": "12345", "customerType": "gold" } }
- 解決方法:
如果
customerType
為「gold」,請使用運算式遮蓋discountCode
欄位。removeFields
函式會從事件中移除特定欄位。例如:message.data.customerType == "gold" ? message.removeFields(["data.discountCode"]) : message
資料轉換
您需要將資料從一種格式或類型轉換為另一種格式或類型。
- 情境:
假設有下列 CloudEvents 資料:
{ "data": { "orderDate": "2024-10-31T12:00:00Z", "totalAmount": "1500" } }
您想編寫 CEL 運算式,產生下列輸出內容:
{ "data": { "orderDate": 1704086400, "totalAmount": 1500.00 } }
- 解決方法:
使用可將
orderDate
轉換為 UNIX 時間戳記的運算式,並將string
型別轉換為double
(浮點數)。totalAmount
setField
函式會新增或取代具有指定鍵的事件欄位。您可以使用字串操作函式轉換字串結果。例如:message .setField("data.orderDate", int(timestamp(message.data.orderDate))) .setField("data.totalAmount", double(message.data.totalAmount))
條件式轉送
您需要根據事件資料,將事件傳送至不同目的地。
- 情境:
假設有下列 CloudEvents 資料:
{ "data": { "eventType": "order.created", "orderValue": 200 } }
您想編寫 CEL 運算式,產生下列輸出內容:
{ "data": { "eventType": "order.created", "orderValue": 200, "routingKey": "highValue" } }
- 解決方法:
如果
orderValue
大於 100,請使用運算式新增含有「highValue」的routingKey
欄位;否則請使用"normal"
。routingKey
欄位可用於判斷路徑。setField
函式會新增或取代具有指定鍵的事件欄位。例如:message.data.orderValue > 100 ? message.setField("data.routingKey", "highValue") : message.setField("data.routingKey", "normal")
預設值處理方式
您必須確保事件酬載中的特定欄位有預設值 (如果沒有)。
- 情境:
假設有下列 CloudEvents 資料:
{ "data": { "itemName": "Product A" } }
您想編寫 CEL 運算式,產生下列輸出內容:
{ "data": { "itemName": "Product A", "quantity": 1 } }
- 解決方法:
如果欄位尚不存在,請使用運算式新增
quantity
欄位,並將預設值設為1
。has
巨集會測試欄位是否可用。setField
函式會新增或取代具有指定鍵的事件欄位。例如:has(message.data.quantity) ? message : message.setField("data.quantity", 1)
字串操作
您需要擷取或修改事件資料中的字串欄位部分。
- 情境:
假設有下列 CloudEvents 資料:
{ "data": { "customerEmail": "alex@example.com" } }
您想編寫 CEL 運算式,產生下列輸出內容:
{ "data": { "customerEmail": "alex@example.com", "emailDomain": "example.com" } }
- 解決方法:
使用運算式從
customerEmail
欄位擷取網域名稱 (「example.com」),並儲存在新的emailDomain
欄位。setField
函式會新增或取代具有指定鍵的事件欄位。extract
規則運算式函式遵循 RE2 語法。例如:message .setField("data.emailDomain", re.extract(message.data.customerEmail, "(^.*@)(.*)", "\\2"))
清單和地圖作業
您需要在事件資料中使用清單或對應。
- 情境:
假設有下列 CloudEvents 資料:
{ "data": { "productIds": [ "product123", "product456" ] } }
您想編寫 CEL 運算式,產生下列輸出內容:
{ "data": { "productIds": [ "product123", "product456" ], "productFound": true } }
- 解決方法:
使用運算式檢查「product456」是否存在於
productIds
清單中,並將結果 (true
或false
) 儲存在新的productFound
欄位中。setField
函式會新增或取代具有指定鍵的事件欄位。exists
巨集會測試清單中所有元素的述詞是否成立,並使用「or」運算子合併結果。例如:message.setField("data.productFound", message.data.productIds.exists(id, id == "product123"))
處理錯誤
您必須妥善處理事件酬載中可能發生的錯誤或非預期資料。
- 情境:
假設有下列 CloudEvents 資料:
{ "data": { "quantity": "abc" } }
您想編寫 CEL 運算式,產生下列輸出內容:
{ "data": { "quantity": 0, "error": "Invalid quantity" } }
- 解決方法:
使用運算式嘗試將
quantity
欄位轉換為整數。如果轉換失敗,請將quantity
欄位設為0
,並新增error
欄位,值為「Invalid quantity」。例如:
// Check if data.quantity exists has(message.data.quantity) && // Check if data.quantity is a string type(message.data.quantity) == string && // Check if string consists of digits message.data.quantity.matches(r'^-?[0-9]+$') ? // If data.quantity is valid, use message message : // If data.quantity is invalid, set to 0 and generate error message .setField("data.quantity", 0) .setField("data.error", "Invalid quantity")
複雜用途
以下列舉一些轉換事件資料的複雜用途。
資料轉換
您需要對巢狀事件資料執行多項轉換。
- 情境:
假設有下列 CloudEvents 資料:
{ "data": { "orderId": "12345", "customer": { "firstName": "Alex", "lastName": "Taylor", "email": "alex@example.com", "address": { "street": "1800 Amphibious Blvd.", "city": "Mountain View", "state": "CA" } }, "items": [ { "itemId": "item1", "price": 10.00, "quantity": 2 }, { "itemId": "item2", "price": 5.00, "quantity": 1 } ] } }
您想編寫 CEL 運算式,產生下列輸出內容:
{ "data": { "orderId": "12345", "customer.firstName": "Alex", "customer.lastName": "Taylor", "customer.email": "a***@example.com", "customer.address.city": "Mountain View", "customer.address.state": "CA" } }
- 解決方法:
使用運算式從地址擷取城市和州別,並遮蓋電子郵件地址。
setField
函式會新增或取代具有指定鍵的事件欄位。toMap
函式會將 CEL 對應清單轉換為單一 CEL 對應。extract
規則運算式函式遵循 RE2 語法。removeFields
函式會從事件中移除特定欄位。denormalize
函式會將深層結構扁平化為鍵/值組合清單。欄位名稱會使用半形句號 (.
) 做為分隔符,區隔結構階層。
例如:
message .setField("data", message.data.setField("customer.address", message.data.customer.address.map(key, key == "city" || key == "state", { key: message.data.customer.address[key] }).toMap()) .setField("customer.email", re.extract(message.data.customer.email, "(^..?).*@(.*)", "\\1***@\\2")) .removeFields(["items"]) .denormalize() )
資料格式和轉送
您需要設定事件資料格式、新增產品資訊,然後傳送事件訊息。
- 情境:
假設有下列 CloudEvents 資料:
{ "data": { "productId": "p123", "productName": "Example Product", "category": "electronics" } }
您想編寫 CEL 運算式,產生下列輸出內容:
{ "data": { "productId": "electronics-p123", "productName": "EXAMPLE PRODUCT", "category": "electronics", "routingKey": "electronics" } }
- 解決方法:
使用運算式將產品名稱格式設為大寫、根據產品類別為產品 ID 加上前置字元,並加入用於後續處理的遞送金鑰。
setField
函式會新增或取代具有指定鍵的事件欄位。upperAscii
函式會傳回字串,並將所有 ASCII 字元轉換為對應的大寫字元。例如:message .setField("data.productId", message.data.category + "-" + message.data.productId) .setField("data.productName", message.data.productName.upperAscii()) .setField("data.routingKey", message.data.category)