Di Toko Nusantara, kerangka IF_ sudah ada sejak artikel Tur Layar, tapi masih kosong. Saya ingin iFlow ini menerima JSON berisi nama pelanggan dan membalas dengan sapaan.
Godaan pertama saya: langsung menulis Groovy yang mengerjakan semuanya. Ternyata lebih enak bertahap, supaya kalau gagal, saya tahu bagian mana yang salah.
Kenapa penting
Tiga tahap ini adalah pola yang akan dipakai di hampir semua iFlow seri ini: balasan sederhana, logika di script, lalu penanganan error. Di ABAP, urutannya mirip dengan menulis program kecil: tampilkan output dulu, tambahkan logika, baru bungkus dengan TRY ..
Konsep
Alur akhirnya seperti ini:
Bagian | Step | Fungsi |
|---|---|---|
Pengirim | HTTPS sender | Menerima request dari Postman di address |
Tahap 1 |
| Membalas teks tetap |
Tahap 2 |
| Membaca nama dari request, membangun balasan |
Tahap 3 |
| Mengubah error menjadi balasan JSON yang rapi |
Nama step mengikuti pola <PREFIX>_.
ikut terkirim
{"customer":
"Pelanggan Demo 01"}Langkah
Persiapan: sender HTTPS
Buka iFlow, klik Edit. Hapus dulu kotak Receiver dari kerangka: iFlow ini sinkron, jadi balasannya kembali ke pengirim lewat koneksi yang sama dan tidak ada sistem tujuan. Receiver baru kita pakai di Series 2 saat CPI memanggil API lain. Lalu hubungkan Sender ke Start dan pilih adapter HTTPS. Di tab Connection, isi Address dengan /. Pengaturan lain biarkan default dulu; soal CSRF Protected kita bahas di artikel berikutnya saat memanggil iFlow dari Postman.
Cara menguji tanpa deploy: Simulation
Setiap tahap diuji dengan Simulation di editor, tanpa deploy. Untuk ABAPer, ini mirip menjalankan function module di SE37: logikanya dites tanpa harus dipanggil dari luar. Caranya sama untuk ketiga tahap:
Pastikan dalam mode Edit, lalu Save.
Klik panah setelah Start, pilih Add Simulation Start Point. Klik panah sebelum End, pilih Add Simulation End Point. Ikon ▶ di toolbar baru aktif setelah keduanya terpasang.
Kalau tahap itu butuh input, klik penanda start point dan isi Body.
Klik ▶ untuk menjalankan.
Klik ikon amplop di end point. Panel bawah menampilkan isi pesan di titik itu: tab Headers, Properties, dan Body.
Tahap 1: balasan tetap
Tambahkan Content Modifier di antara Start dan End, beri nama CM_.
Tab Message Header: tambahkan
Content-dengan nilaiType application/.json Tab Message Body: tipe Constant, isi
{"message":. Isinya teks tetap tanpa variabel, jadi Constant sudah cukup."Halo dari Toko Nusantara!"}
Uji: jalankan Simulation tanpa input. CM_ tidak membaca body yang masuk; body itu ditimpa dengan teks tetap tadi, jadi input kosong tidak masalah.
Input body | Hasil di tab Body |
|---|---|
(kosong) |
|
Tahap 2: baca request dengan Groovy
Ganti CM_ dengan Groovy Script bernama GS_, lalu buat script baru Build:
import com.sap.gateway.ip.core.customdev.util.Message
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
def Message processData(Message message) {
def bodyText = message.getBody(java.io.Reader)?.text
if (!bodyText?.trim()) {
throw new IllegalArgumentException("Body request kosong")
}
def request = new JsonSlurper().parseText(bodyText)
def customer = request?.customer
if (!customer) {
throw new IllegalArgumentException("Field 'customer' wajib diisi")
}
// Catatan kurir: dipakai di dalam iFlow saja
message.setProperty("p_customer", customer)
// Custom header di Message Processing Log, supaya pesan bisa dicari per pelanggan
def messageLog = messageLogFactory.getMessageLog(message)
messageLog?.addCustomHeaderProperty("Log_Customer", customer.toString())
def reply = [message: "Halo ${customer}, salam dari Toko Nusantara!".toString()]
message.setBody(JsonOutput.toJson(reply))
message.setHeader("Content-Type", "application/json")
return message
}
Beberapa hal yang sengaja saya lakukan:
Body diambil dengan
message., dibaca jadi teks, dicek tidak kosong, baru di-parse denganget Body(java. io. Reader) parse. Alasan saya tidak memakaiText parse(reader)ada di bagian jebakan.addmenambahkan kolom yang bisa dicari di Monitor. AwalanCustom Header Property Log_menandai bahwa nilai ini khusus untuk pencarian di log; aturan lengkapnya ada di artikel Naming Convention supaya iFlow Mudah Dibaca di akhir Series 1. Untuk ABAPer, ini mirip menambahkan external number di SLG1 supaya log bisa difilter.?.mencegah error kalaumessagetidak tersedia, misalnya saat Simulation.Log
Uji: kali ini input wajib diisi, karena script membaca nama pelanggan dari body. Tanpa input, Simulation berhenti dengan Body request kosong.
Input body | Hasil |
|---|---|
| Body: |
Tahap 3: tangani error
Sebelum menambah apa pun, jalankan Simulation tahap 2 sekali lagi dengan input {}. Simulation berhenti dengan error dari GS_: Field 'customer' wajib diisi. Kalau iFlow ini dipanggil dari luar dalam kondisi begini, pemanggil hanya menerima error teknis yang tidak jelas.
Tambahkan Exception Subprocess di dalam Integration Process, beri nama EXS_. Di dalamnya, antara Error Start dan End:
Content Modifier
CM_:Build Error Reply Header
Camel=Http Response Code 400Header
Content-=Type application/json Body tipe Expression:
{"error":. Kali ini harus Expression, karena"Request tidak valid", "detail": "${exception. message}"} ${exception.perlu diganti dengan isi pesan error saat itu.message}
Akhiri dengan End Message, supaya pemanggil menerima balasan di atas, bukan error mentah.
Exception Subprocess ini padanan TRY . di ABAP: logika utama tetap bersih, penanganan error ada di satu tempat.
Uji: Simulation tidak mendukung Exception Subprocess; ia hanya bisa menjalankan alur utama. Jadi untuk tahap ini kita langsung deploy, lalu membuktikannya dengan pesan sungguhan dari Postman di artikel berikutnya: body {} harus dibalas JSON error dengan status 400.
Deploy
Klik Save as Version dengan komentar Hello World 3 stages, lalu Deploy. Tunggu sampai statusnya Started di Monitor → Manage Integration Content.
Jebakan yang saya temui
Constant atau Expression? Di Constant,
${.tidak diproses: teks. . } ${exception.akan tampil apa adanya di balasan. Pakai Expression hanya kalau body memang berisi variabel; untuk teks tetap, Constant lebih jelas maksudnya.message} Body kosong menghasilkan error yang menyesatkan. Versi pertama script saya langsung memanggil
new Json. Saat Simulation dijalankan tanpa input, error-nya: "Unable to determine the current character... The current character read is '⋮' with an int value of 0", diikuti deretan karakter kosong. Kedengarannya seperti masalah encoding, padahal body-nya memang kosong. Dengan membaca body jadi teks dulu dan mengecek kosong atau tidak, pesan error-nya berubah jadi jelas: Body request kosong.Slurper(). parse(reader) Simulation tidak mendukung Exception Subprocess. Start point dan end point hanya bisa dipasang di satu alur, jadi penanganan error baru bisa diuji setelah deploy, dengan pesan sungguhan.
Tombol Simulation abu-abu. Ikon ▶ di toolbar baru aktif setelah simulation start point dan simulation end point dipasang di panah alur. Tanpa keduanya, Simulation tidak bisa dijalankan sama sekali.
Exception Subprocess dengan End Message vs Error End. Pilihannya menentukan apakah pemanggil menerima balasan rapi atau status gagal. Aturan lengkapnya kita bahas di Series 5, artikel End Message atau Error End?.
Ringkasan
Bangun iFlow bertahap: balasan tetap, logika di Groovy, lalu penanganan error.
Baca body dengan
message.; tambahkan custom header di MPL untuk memudahkan pencarian.get Body(java. io. Reader) Exception Subprocess dengan End Message adalah
TRY .versi CPI.. . CATCH Uji alur utama dengan Simulation sebelum memanggil dari luar; penanganan error baru bisa dibuktikan dengan pesan sungguhan.
Berikutnya: iFlow sudah Started. Kita panggil dari Postman memakai service key yang dibuat di artikel kedua, lengkap dengan token OAuth dan urusan CSRF.



