Di Toko Nusantara, saya ingin iFlow pertama yang sederhana: terima order dalam bentuk JSON, ambil nomor ordernya, lalu teruskan ke sistem lain. Di ABAP, saya tinggal menyimpan nomor order itu ke sebuah variabel lalu memakainya di mana saja.
Di CPI, saya bingung: nomor order itu disimpan di mana? Ada tiga tempat yang tampak mirip, yaitu body, header, dan property. Content Modifier punya tab untuk ketiganya, Groovy punya method untuk ketiganya, dan semuanya terlihat bisa dipakai. Ternyata pilihan di antara ketiganya menentukan apakah data itu ikut terkirim ke luar atau tidak.
Kenapa penting
Hampir semua step di iFlow membaca atau menulis salah satu dari tiga tempat ini. Salah pilih biasanya tidak langsung error. Akibatnya baru terasa belakangan, misalnya data internal ikut terkirim ke sistem tujuan, atau nilai yang sudah disimpan tiba-tiba "hilang" di iFlow berikutnya. Artikel-artikel setelah ini akan sering kembali ke tiga tempat tersebut.
Konsep: amplop dan catatan kurir
Bayangkan CPI sebagai kantor kurir. Setiap pesan yang lewat adalah sebuah amplop:
Body adalah isi surat di dalam amplop, yaitu data utamanya, misalnya JSON order dari Toko Nusantara.
Header adalah tulisan di bagian luar amplop: alamat, perangko, cap "penting". Header ikut berpindah bersama amplop dan bisa ikut terkirim ke sistem tujuan, misalnya sebagai HTTP header.
Property adalah catatan yang ditulis kurir di buku catatannya sendiri selama amplop diproses. Catatan ini tidak ditempel ke amplop, jadi tidak ikut terkirim ke luar.
Untuk ABAPer, padanan yang paling dekat adalah IDoc:
CPI | Analogi amplop | Padanan ABAP |
|---|---|---|
Body | Isi surat | Data record IDoc (segmen data) |
Header | Tulisan di luar amplop | Control record IDoc (EDIDC): ikut terkirim, menjelaskan pesan |
Property | Catatan kurir | Variabel lokal di function module yang memproses IDoc: hanya hidup selama proses berjalan |
Cara membaca dan menulisnya
Di Content Modifier, ketiganya punya tab sendiri: Message Header, Exchange Property, dan Message Body. Untuk membaca nilainya di field lain, CPI memakai ekspresi:
Yang dibaca | Ekspresi |
|---|---|
Header |
|
Property |
|
Body |
|
Di Groovy, method-nya juga terpisah. Contoh berikut membaca order dari body, lalu menyimpan nomornya di dua tempat sekaligus supaya bedanya terlihat:
import com.sap.gateway.ip.core.customdev.util.Message
import groovy.json.JsonSlurper
def Message processData(Message message) {
def body = message.getBody(java.io.Reader)
def order = new JsonSlurper().parse(body)
// Catatan kurir: dipakai untuk logika di dalam iFlow, tidak ikut terkirim
message.setProperty("p_orderId", order.orderId)
// Tulisan di amplop: bisa ikut terkirim ke sistem tujuan
message.setHeader("X-TKN-Order-Id", order.orderId)
return message
}
Body dibaca dengan message., bukan sebagai String. Dengan Reader, script bisa langsung memprosesnya, seperti Json di atas, tanpa membuat salinan String lebih dulu. Di artikel berikutnya saya sering menambahkan . supaya body kosong bisa dicek sebelum di-parse. Untuk pesan kecil seperti demo di blog ini, itu tidak masalah. Hanya saja . tetap memuat seluruh body ke memori, jadi untuk pesan besar lebih aman membaca langsung dari Reader. Kebiasaan memakai Reader ini saya pakai di semua script seri ini.
Kapan memakai yang mana
Aturan praktis yang saya pakai:
Kebutuhan | Pakai |
|---|---|
Data utama yang diolah atau dikirim | Body |
Informasi yang memang perlu sampai ke sistem tujuan (Content-Type, ID referensi untuk penerima) | Header |
Nilai sementara untuk logika iFlow: counter, flag, nomor order untuk log, salinan body asli | Property |
Nilai yang harus dibawa ke iFlow lain lewat ProcessDirect | Header |
Kalau ragu, mulai dari property. Property tidak pernah keluar dari iFlow, jadi paling aman. Pindahkan ke header hanya kalau nilai itu memang harus ikut terkirim bersama amplop.
Jebakan yang saya temui
Property tidak menyeberang ke iFlow lain. Saat sebuah iFlow memanggil iFlow lain lewat ProcessDirect, yang ikut hanya body dan header. Property yang sudah susah payah diisi tidak ada di iFlow tujuan. Kalau perlu dibawa, pindahkan dulu ke header. Pola ini kita pakai lagi di Series 2 saat membuat subflow gateway.
Header bisa bocor ke luar. Karena header menempel di amplop, nilai yang tidak seharusnya dibaca sistem tujuan bisa ikut terkirim, misalnya penanda internal atau data sensitif. Apakah sebuah header akhirnya terkirim atau tidak juga bergantung pada adapter dan pengaturannya. Detailnya, termasuk kasus sebaliknya (header yang tidak pernah sampai), kita bahas di Series 2, artikel Header yang Tidak Pernah Sampai.
Isi body berubah, property tidak. Banyak step mengganti body, misalnya Request Reply yang menimpa body dengan jawaban API. Kalau body asli masih dibutuhkan setelahnya, simpan dulu salinannya di property.
Ringkasan
Body adalah isi surat, header adalah tulisan di luar amplop, property adalah catatan kurir.
Header bisa ikut terkirim ke sistem tujuan; property tidak pernah keluar dari iFlow.
Ke iFlow lain lewat ProcessDirect, yang ikut hanya body dan header.
Kalau ragu, simpan di property; pindahkan ke header hanya kalau nilainya perlu ikut terkirim.
Di Groovy, baca body dengan
message..get Body(java. io. Reader)
Berikutnya: sebelum membuat iFlow pertama, kita tur dulu layar-layar yang akan dipakai setiap hari: Design, Monitor, dan editor iFlow.