Pesan di CPI Itu Seperti Amplop: Body, Header, dan Property

Konsep dasar sebelum membuat iFlow: apa bedanya body, header, dan property, mana yang ikut terkirim, dan kapan memakai yang mana.

Daftar isi6 bagian

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

${header.X-TKN-Order-Id}

Property

${property.p_orderId}

Body

${in.body}

Di Groovy, method-nya juga terpisah. Contoh berikut membaca order dari body, lalu menyimpan nomornya di dua tempat sekaligus supaya bedanya terlihat:

Groovy
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.getBody(java.io.Reader), bukan sebagai String. Dengan Reader, script bisa langsung memprosesnya, seperti JsonSlurper().parse(body) di atas, tanpa membuat salinan String lebih dulu. Di artikel berikutnya saya sering menambahkan .text supaya body kosong bisa dicek sebelum di-parse. Untuk pesan kecil seperti demo di blog ini, itu tidak masalah. Hanya saja .text 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.getBody(java.io.Reader).

Berikutnya: sebelum membuat iFlow pertama, kita tur dulu layar-layar yang akan dipakai setiap hari: Design, Monitor, dan editor iFlow.