Contoh transformasi

Anda dapat mengubah data CloudEvents dengan menulis ekspresi transformasi menggunakan CEL. Untuk mengetahui informasi selengkapnya, lihat Mengubah peristiwa yang diterima.

Berikut adalah beberapa kasus penggunaan umum dan contoh yang menunjukkan cara menulis ekspresi CEL untuk mengubah data peristiwa.

Kasus penggunaan standar

Berikut adalah beberapa kasus penggunaan standar saat mengubah data peristiwa.

Normalisasi data

Anda perlu meratakan struktur data bertingkat dalam pesan peristiwa untuk memungkinkan pemrosesan yang lebih mudah oleh layanan downstream.

Skenario:

Dengan data CloudEvents berikut:

{
  "data": {
    "orderId": "12345",
    "customer": {
      "firstName": "Alex",
      "lastName": "Taylor",
      "address": {
        "street": "1800 Amphibious Blvd.",
        "city": "Mountain View"
      }
    }
  }
}

Anda ingin menulis ekspresi CEL yang menghasilkan output berikut:

{
  "data": {
    "orderId": "12345",
    "customerFirstName": "Alex",
    "customerLastName": "Taylor",
    "customerStreet": "1800 Amphibious Blvd.",
    "customerCity": "Mountain View"
  }
}
Solusi 1:

Memformat data output secara manual. Hal ini memungkinkan Anda mencantumkan nama kolom dan hanya memilih elemen yang diperlukan dalam output. Ini adalah pendekatan yang wajar jika input dapat diprediksi dan jika jumlah kolom rendah. Fungsi setField menambahkan atau mengganti kolom peristiwa dengan kunci tertentu. Contoh:

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,
})
Solusi 2:

Gunakan fungsi dalam ekspresi Anda. Fungsi setField menambahkan atau mengganti kolom peristiwa dengan kunci tertentu. Fungsi denormalize membuat struktur mendalam menjadi daftar pasangan kunci dan nilai. Nama kolom dibatasi menggunakan titik (.) untuk menyegmentasikan hierarki struktur. Contoh:

message.setField("data", message.data.denormalize())

Hal ini menghasilkan output berikut yang sedikit berbeda dari payload yang diharapkan. Namun, keuntungannya mencakup ekspresi CEL yang lebih singkat yang beroperasi pada input apa pun, dan yang secara otomatis menyertakan sejumlah kolom masuk.

{
  "data": {
    "orderId": "12345",
    "customer.firstName": "Alex",
    "customer.lastName": "Taylor",
    "customer.address.street": "1800 Amphibious Blvd.",
    "customer.address.city": "Mountain View"
  }
}

Data masking

Anda perlu menyamarkan data sensitif dalam payload peristiwa sebelum dikirim ke lingkungan yang kurang aman.

Skenario:

Dengan data CloudEvents berikut:

{
  "data": {
    "userId": "user123",
    "email": "alex@example.com",
    "creditCardNumber": "1234-5678-9012-3456"
  }
}

Anda ingin menulis ekspresi CEL yang menghasilkan output berikut:

{
  "data": {
    "userId": "user123",
    "email": "a***@example.com",
    "creditCardNumber": "xxxx-xxxx-xxxx-3456"
  }
}
Solusi:

Gunakan ekspresi untuk menyamarkan informasi sensitif seperti alamat email dan nomor kartu kredit. Fungsi setField menambahkan atau mengganti kolom peristiwa dengan kunci tertentu. Fungsi ekspresi reguler extract mengikuti sintaksis RE2. Contoh:

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"))

Penyamaran data

Anda perlu menghapus kolom tertentu dari payload peristiwa berdasarkan kondisi tertentu.

Skenario:

Dengan data CloudEvents berikut:

{
  "data": {
    "orderId": "12345",
    "customerType": "gold",
    "discountCode": "VIP"
  }
}

Anda ingin menulis ekspresi CEL yang menghasilkan output berikut:

{
  {
  "orderId": "12345",
  "customerType": "gold"
  }
}
Solusi:

Gunakan ekspresi yang menyamarkan kolom discountCode jika customerType adalah "gold". Fungsi removeFields akan menghapus kolom tertentu dari peristiwa. Contoh:

message.data.customerType == "gold" ?
      message.removeFields(["data.discountCode"]) :
      message

Konversi data

Anda perlu mengonversi data dari satu format atau jenis ke format atau jenis lainnya.

Skenario:

Dengan data CloudEvents berikut:

{
  "data": {
    "orderDate": "2024-10-31T12:00:00Z",
    "totalAmount": "1500"
  }
}

Anda ingin menulis ekspresi CEL yang menghasilkan output berikut:

{
  "data": {
    "orderDate": 1704086400,
    "totalAmount": 1500.00
  }
}
Solusi:

Gunakan ekspresi yang mengonversi orderDate menjadi stempel waktu UNIX, dan jenis totalAmount dari string menjadi double (angka floating point). Fungsi setField menambahkan atau mengganti kolom peristiwa dengan kunci tertentu. Anda dapat menggunakan fungsi manipulasi string untuk mengonversi hasil string. Contoh:

message
      .setField("data.orderDate", int(timestamp(message.data.orderDate)))
      .setField("data.totalAmount", double(message.data.totalAmount))

Pemilihan rute bersyarat

Anda perlu merutekan peristiwa ke berbagai tujuan berdasarkan data peristiwa.

Skenario:

Dengan data CloudEvents berikut:

{
  "data": {
    "eventType": "order.created",
    "orderValue": 200
  }
}

Anda ingin menulis ekspresi CEL yang menghasilkan output berikut:

{
  "data": {
    "eventType": "order.created",
    "orderValue": 200,
    "routingKey": "highValue"
  }
}
Solusi:

Gunakan ekspresi yang menambahkan kolom routingKey dengan "highValue" jika orderValue lebih besar dari 100; jika tidak, "normal". Kolom routingKey dapat digunakan untuk menentukan jalur pemilihan rute. Fungsi setField menambahkan atau mengganti kolom peristiwa dengan kunci tertentu. Contoh:

message.data.orderValue > 100 ?
      message.setField("data.routingKey", "highValue") :
      message.setField("data.routingKey", "normal")

Penanganan nilai default

Anda harus memastikan bahwa kolom tertentu dalam payload peristiwa memiliki nilai default jika tidak ada.

Skenario:

Dengan data CloudEvents berikut:

{
  "data": {
    "itemName": "Product A"
  }
}

Anda ingin menulis ekspresi CEL yang menghasilkan output berikut:

{
  "data": {
    "itemName": "Product A",
    "quantity": 1
  }
}
Solusi:

Gunakan ekspresi yang menambahkan kolom quantity dengan nilai default 1 jika kolom tersebut belum ada. Makro has menguji apakah kolom tersedia. Fungsi setField menambahkan atau mengganti kolom peristiwa dengan kunci tertentu. Contoh:

has(message.data.quantity)  ?
    message :
    message.setField("data.quantity", 1)

Manipulasi string

Anda perlu mengekstrak atau mengubah bagian kolom string dalam data peristiwa.

Skenario:

Dengan data CloudEvents berikut:

{
  "data": {
    "customerEmail": "alex@example.com"
  }
}

Anda ingin menulis ekspresi CEL yang menghasilkan output berikut:

{
  "data": {
    "customerEmail": "alex@example.com",
    "emailDomain": "example.com"
  }
}
Solusi:

Gunakan ekspresi yang mengekstrak nama domain ("example.com") dari kolom customerEmail dan menyimpannya di kolom emailDomain baru. Fungsi setField menambahkan atau mengganti kolom peristiwa dengan kunci tertentu. Fungsi ekspresi reguler extract mengikuti sintaksis RE2. Contoh:

message
  .setField("data.emailDomain",
re.extract(message.data.customerEmail, "(^.*@)(.*)", "\\2"))

Mencantumkan dan memetakan operasi

Anda perlu menggunakan daftar atau peta dalam data peristiwa.

Skenario:

Dengan data CloudEvents berikut:

{
  "data": {
    "productIds": [
      "product123",
      "product456"
    ]
  }
}

Anda ingin menulis ekspresi CEL yang menghasilkan output berikut:

{
  "data": {
    "productIds": [
      "product123",
      "product456"
    ],
    "productFound": true
  }
}
Solusi:

Gunakan ekspresi yang memeriksa apakah "product456" ada dalam daftar productIds dan menyimpan hasilnya (true atau false) di kolom productFound baru. Fungsi setField menambahkan atau mengganti kolom peristiwa dengan kunci tertentu. Makro exists menguji apakah predikat berlaku untuk semua elemen daftar dan menggabungkan hasilnya dengan operator "or". Contoh:

message.setField("data.productFound",
        message.data.productIds.exists(id, id == "product123"))

Penanganan error

Anda harus menangani potensi error atau data yang tidak terduga dengan baik dalam payload peristiwa.

Skenario:

Dengan data CloudEvents berikut:

{
  "data": {
    "quantity": "abc"
  }
}

Anda ingin menulis ekspresi CEL yang menghasilkan output berikut:

{
  "data": {
    "quantity": 0,
    "error": "Invalid quantity"
  }
}
Solusi:

Gunakan ekspresi yang mencoba mengonversi kolom quantity menjadi bilangan bulat. Jika konversi gagal, tetapkan kolom quantity ke 0, dan tambahkan kolom error baru dengan nilai "Jumlah tidak valid".

  • Makro has menguji apakah kolom tersedia.
  • Fungsi type menampilkan jenis nilai.
  • Fungsi ekspresi reguler matches mengikuti sintaksis RE2.
  • Fungsi setField menambahkan atau mengganti kolom peristiwa dengan kunci tertentu.

Contoh:

// 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")

Kasus penggunaan yang kompleks

Berikut adalah beberapa kasus penggunaan yang kompleks saat mengubah data peristiwa.

Transformasi data

Anda perlu melakukan beberapa transformasi pada data peristiwa bertingkat.

Skenario:

Dengan data CloudEvents berikut:

{
  "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
      }
    ]
  }
}

Anda ingin menulis ekspresi CEL yang menghasilkan output berikut:

{
  "data": {
    "orderId": "12345",
    "customer.firstName": "Alex",
    "customer.lastName": "Taylor",
    "customer.email": "a***@example.com",
    "customer.address.city": "Mountain View",
    "customer.address.state": "CA"
  }
}
Solusi:

Gunakan ekspresi yang mengekstrak kota dan negara bagian dari alamat, dan yang menyamarkan alamat email.

  • Fungsi setField menambahkan atau mengganti kolom peristiwa dengan kunci tertentu.
  • Fungsi toMap mengonversi daftar CEL peta CEL menjadi satu peta CEL.
  • Fungsi ekspresi reguler extract mengikuti sintaksis RE2.
  • Fungsi removeFields menghapus kolom tertentu dari peristiwa.
  • Fungsi denormalize membuat struktur mendalam menjadi daftar pasangan kunci dan nilai. Nama kolom dibatasi menggunakan titik (.) untuk menyegmentasikan hierarki struktur.

Contoh:

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()
)

Pemformatan dan pemilihan rute data

Anda perlu memformat data peristiwa, menambahkan informasi produk, lalu merutekan pesan peristiwa.

Skenario:

Dengan data CloudEvents berikut:

{
  "data": {
    "productId": "p123",
    "productName": "Example Product",
    "category": "electronics"
  }
}

Anda ingin menulis ekspresi CEL yang menghasilkan output berikut:

{
  "data": {
    "productId": "electronics-p123",
    "productName": "EXAMPLE PRODUCT",
    "category": "electronics",
    "routingKey": "electronics"
  }
}
Solusi:

Gunakan ekspresi yang memformat nama produk menjadi huruf besar, menambahkan awalan ke ID produk berdasarkan kategorinya, dan menyertakan kunci pemilihan rute untuk pemrosesan downstream. Fungsi setField menambahkan atau mengganti kolom peristiwa dengan kunci tertentu. Fungsi upperAscii menampilkan string dengan semua karakter ASCII yang dikonversi ke karakter huruf besar yang sesuai. Contoh:

message
.setField("data.productId",
message.data.category + "-" + message.data.productId)
.setField("data.productName", message.data.productName.upperAscii())
.setField("data.routingKey", message.data.category)