Integrasi aman dengan API pihak ketiga agar aplikasi tetap berjalan saat outage. Pelajari timeout, retry, circuit breaker, dan pengecekan cepat.

API pihak ketiga bisa gagal dengan cara yang tidak terlihat seperti kejadian "mati" yang jelas. Masalah paling umum adalah melambat: permintaan menggantung, respons datang terlambat, dan aplikasi Anda terus menunggu. Jika panggilan tersebut berada di jalur kritis, gangguan kecil di luar kendali Anda menumpuk di dalam sistem.
Begitulah perlambatan lokal menjadi outage penuh. Thread atau worker terjebak menunggu, antrean membesar, transaksi database tetap terbuka lebih lama, dan permintaan baru mulai mengalami timeout. Tak lama kemudian, bahkan halaman yang tidak menggunakan API eksternal terasa rusak karena sistem kewalahan oleh pekerjaan yang menunggu.
Dampaknya nyata. Penyedia identitas yang tidak stabil memblokir pendaftaran dan login. Timeout gateway pembayaran membekukan proses checkout, membuat pengguna bingung apakah mereka sudah dibebankan. Penundaan pesan menghentikan reset kata sandi dan konfirmasi pesanan, yang memicu gelombang retry dan tiket dukungan.
Tujuannya sederhana: isolasi kegagalan eksternal agar alur kerja inti tetap berjalan. Itu bisa berarti membiarkan pengguna membuat pesanan lalu mengonfirmasi pembayaran kemudian, atau mengizinkan pendaftaran meski email sambutan gagal.
Metrik keberhasilan praktis: ketika penyedia lambat atau down, aplikasi Anda tetap merespons cepat dan jelas, serta radius dampak tetap kecil. Misalnya, sebagian besar permintaan inti masih selesai dalam anggaran latensi normal, kegagalan tetap terbatas pada fitur yang bergantung pada API tersebut, pengguna melihat status yang jelas (queued, pending, coba lagi nanti), dan pemulihan terjadi otomatis saat penyedia kembali.
Sebagian besar kegagalan dapat diprediksi, meskipun waktunya tidak. Sebutkan di depan dan Anda bisa memutuskan apa yang harus di-retry, apa yang harus dihentikan, dan apa yang ditampilkan ke pengguna.
Kategori umum:
Tidak semua error berarti hal yang sama. Masalah sementara sering layak di-retry karena panggilan berikutnya mungkin berhasil (gangguan jaringan, timeout, 502/503, dan beberapa 429 setelah menunggu). Masalah permanen biasanya tidak akan memperbaiki dirinya sendiri (kredensial tidak valid, endpoint salah, request yang salah format, penolakan izin).
Memperlakukan semua error sama bisa mengubah insiden kecil menjadi downtime. Mengulang kegagalan permanen membuang-buang waktu, mempercepat pemakaian kuota, dan membangun antrean yang memperlambat semuanya. Tidak pernah mencoba ulang pada kegagalan sementara memaksa pengguna mengulang tindakan dan kehilangan pekerjaan yang seharusnya selesai beberapa saat kemudian.
Perhatikan ekstra alur kerja di mana jeda terasa seperti kegagalan: checkout, login, reset kata sandi, dan notifikasi (email/SMS/push). Lonjakan dua detik pada API marketing mengganggu. Lonjakan dua detik pada otorisasi pembayaran memblokir pendapatan.
Tes yang berguna: "Apakah panggilan ini harus selesai untuk menyelesaikan tugas utama pengguna saat ini?" Jika ya, Anda perlu timeout ketat, retry hati-hati, dan jalur kegagalan yang jelas. Jika tidak, pindahkan ke antrean dan jaga aplikasi tetap responsif.
Timeout adalah waktu maksimum Anda bersedia menunggu sebelum berhenti dan melanjutkan. Tanpa batas yang jelas, satu penyedia lambat bisa menumpuk permintaan yang menunggu dan memblokir pekerjaan penting.
Ada dua jenis tunggu yang membantu dipisahkan:
Memilih angka bukan soal kesempurnaan. Ini soal mencocokkan kesabaran manusia dan alur kerja Anda.
Cara praktis memilih timeout adalah mundur dari pengalaman:
Tradeoff nyata: terlalu lama dan Anda mengikat thread, worker, dan koneksi database. Terlalu singkat dan Anda menciptakan false failure dan memicu retry yang tidak perlu.
Retry berguna ketika kegagalan kemungkinan bersifat sementara: gangguan jaringan singkat, DNS hiccup, atau 500/502/503 satu kali. Dalam kasus tersebut, coba lagi kedua bisa berhasil dan pengguna tak menyadari apapun.
Risikonya adalah retry storm. Ketika banyak klien gagal bersamaan dan semuanya retry sekaligus, mereka dapat membebani penyedia (dan worker Anda sendiri). Backoff dan jitter mencegah itu.
Anggaran retry menjaga Anda tetap masuk akal. Batasi percobaan dan batasi total waktu agar alur kerja inti tidak terjebak menunggu pihak lain.
Jangan retry error klien yang dapat diprediksi seperti 400/422 masalah validasi, 401/403 masalah otentikasi, atau 404. Itu hampir pasti akan gagal lagi dan hanya menambah beban.
Satu pengaman lagi: hanya retry operasi tulis (POST/PUT) ketika Anda memiliki idempotensi, jika tidak Anda berisiko double-charge atau duplikasi data.
Idempotensi berarti Anda bisa menjalankan permintaan yang sama dua kali dan berakhir dengan hasil final yang sama. Itu penting karena retry adalah hal biasa: jaringan drop, server restart, dan klien timeout. Tanpa idempotensi, retry yang "membantu" menghasilkan duplikasi dan masalah uang nyata.
Bayangkan checkout: API pembayaran lambat, aplikasi Anda timeout, dan Anda retry. Jika panggilan pertama sebenarnya berhasil, retry bisa menyebabkan tagihan ganda. Risiko yang sama ada pada tindakan seperti membuat pesanan, memulai langganan, mengirim email/SMS, mengeluarkan pengembalian dana, atau membuat tiket dukungan.
Perbaikannya adalah menempelkan kunci idempotensi (atau request ID) ke setiap panggilan "melakukan sesuatu". Kunci itu harus unik per aksi pengguna, bukan per percobaan. Penyedia (atau layanan Anda sendiri) menggunakan kunci itu untuk mendeteksi duplikat dan mengembalikan hasil yang sama alih-alih melakukan aksi lagi.
Perlakukan kunci idempotensi seperti bagian dari model data, bukan header yang Anda harap tidak ada yang lupa.
Buat satu kunci saat pengguna memulai aksi (misalnya saat mereka klik Pay), lalu simpan bersama catatan lokal Anda.
Pada setiap percobaan:
Jika Anda adalah "penyedia" untuk panggilan internal, tegakkan perilaku yang sama di sisi server.
Circuit breaker adalah sakelar pengaman. Ketika layanan eksternal mulai gagal, Anda berhenti memanggilnya untuk periode singkat daripada menumpuk permintaan yang kemungkinan besar akan timeout.
Circuit breaker biasanya punya tiga status:
Saat breaker terbuka, aplikasi Anda harus melakukan sesuatu yang dapat diprediksi. Jika API validasi alamat down saat pendaftaran, terima alamat dan tandai untuk ditinjau nanti. Jika pemeriksaan risiko pembayaran down, antre pesanan untuk tinjauan manual atau nonaktifkan opsi itu sementara dan jelaskan alasan.
Pilih ambang yang sesuai dampak pengguna:
Jaga cooldown singkat (detik sampai menit) dan batasi probe half-open. Tujuannya melindungi alur kerja inti dulu, lalu pulih cepat.
Saat API eksternal lambat atau down, tujuan Anda adalah membuat pengguna tetap bergerak. Itu berarti punya Plan B yang jujur tentang apa yang terjadi.
Fallback adalah apa yang dilakukan aplikasi ketika API tidak merespons tepat waktu. Opsi termasuk menggunakan data cache, beralih ke mode terdegradasi (sembunyikan widget tidak penting, nonaktifkan aksi opsional), meminta input pengguna alih-alih memanggil API (masukan alamat manual), atau menampilkan pesan jelas dengan langkah selanjutnya.
Jujur: jangan bilang sesuatu selesai jika tidak.
Jika pekerjaan tidak harus selesai dalam permintaan pengguna, dorong ke antrean dan respons cepat. Kandidat umum: mengirim email, sinkron ke CRM, menghasilkan laporan, dan posting event analytics.
Gagal cepat untuk aksi inti. Jika API tidak diperlukan untuk menyelesaikan checkout (atau pembuatan akun), jangan blokir permintaan. Terima pesanan, antre panggilan eksternal, dan rekonsiliasi nanti. Jika API diperlukan (misalnya otorisasi pembayaran), gagal cepat dengan pesan yang jelas dan jangan membuat pengguna menunggu.
Apa yang dilihat pengguna harus mencerminkan apa yang terjadi di belakang layar: status jelas (completed, pending, failed), janji yang bisa ditepati (struk sekarang, konfirmasi nanti), cara untuk mencoba ulang, dan catatan yang terlihat di UI (log aktivitas, badge pending).
Rate limit adalah cara penyedia mengatakan, "Anda boleh memanggil kami, tapi tidak terlalu sering." Anda akan menemukannya lebih cepat daripada perkiraan: lonjakan lalu lintas, job latar yang berjalan bersamaan, atau bug yang melakukan loop saat error.
Mulailah dengan mengontrol berapa banyak permintaan yang Anda buat. Gabungkan batch bila mungkin, cache respons bahkan selama 30–60 detik bila aman, dan throttle di sisi klien agar aplikasi Anda tidak meledak lebih cepat dari yang penyedia izinkan.
Saat Anda mendapat 429 Too Many Requests, perlakukan itu sebagai sinyal untuk memperlambat.
Retry-After ketika disediakan.Juga batasi concurrency. Satu alur kerja (misalnya sinkronisasi kontak) tidak boleh menghabiskan semua slot worker dan membuat alur kritis seperti login atau checkout kelaparan. Pool terpisah atau batas per-fitur membantu.
Setiap panggilan pihak ketiga butuh rencana untuk kegagalan. Anda tidak perlu sempurna. Anda butuh perilaku yang dapat diprediksi saat penyedia sedang bermasalah.
Tentukan apa yang terjadi jika panggilan gagal saat ini. Perhitungan pajak saat checkout mungkin harus-selesai. Sinkron kontak marketing biasanya bisa menunggu. Pilihan ini menentukan semuanya.
Pilih timeout per jenis panggilan dan jaga konsistensi. Lalu tetapkan anggaran retry agar Anda tidak terus-menerus memukul API yang lambat.
Jika permintaan bisa membuat sesuatu atau menagih uang, tambahkan kunci idempotensi dan simpan catatan permintaan. Jika request pembayaran timeout, retry tidak boleh menggandakan tagihan. Pelacakan juga membantu dukungan menjawab, "Apakah ini berhasil?"
Saat error melonjak, hentikan pemanggilan penyedia untuk periode singkat. Untuk panggilan harus-selesai, tampilkan jalur "Coba lagi" yang jelas. Untuk panggilan bisa-tunggu, antre pekerjaan dan proses nanti.
Lacak latensi, tingkat error, dan event open/close breaker. Beri alert pada perubahan yang berkelanjutan, bukan sekadar blip tunggal.
Sebagian besar outage API tidak dimulai besar. Mereka menjadi besar karena aplikasi Anda bereaksi dengan cara terburuk: menunggu terlalu lama, retry terlalu agresif, dan mengikat worker yang sama yang menjalankan semuanya.
Pola berikut menyebabkan efek berantai:
Perbaikan kecil mencegah outage besar: retry hanya error yang kemungkinan sementara (timeout, beberapa 429, beberapa 5xx) dan batasi percobaan dengan backoff dan jitter; jaga timeout singkat dan disengaja; wajibkan idempotensi untuk operasi yang membuat/menagih; dan desain untuk outage parsial.
Sebelum push integrasi ke produksi, lakukan pemeriksaan cepat dengan pola pikir kegagalan. Jika Anda tidak bisa menjawab "ya" pada item, anggap itu sebagai blocker rilis untuk alur inti seperti signup, checkout, atau pengiriman pesan.
Jika penyedia pembayaran mulai timeout, perilaku yang benar adalah "checkout tetap terbuka, pengguna mendapat pesan jelas, dan Anda tidak menggantung selamanya," bukan "semua tergantung sampai timeout."
Bayangkan checkout yang memanggil tiga layanan: API pembayaran untuk men-charge kartu, API pajak untuk menghitung pajak, dan API email untuk mengirim struk.
Panggilan pembayaran adalah satu-satunya yang harus sinkron. Masalah pada pajak atau email tidak boleh melumpuhkan pembelian.
Misalnya API pajak kadang memakan 8–15 detik. Jika checkout menunggu, pengguna meninggalkan keranjang dan app mengikat worker.
Alur yang lebih aman:
Hasil: lebih sedikit keranjang yang ditinggalkan dan lebih sedikit pesanan macet ketika penyedia pajak lambat.
Email struk penting, tapi tidak boleh memblokir capture pembayaran. Jika API email gagal, pemutus sirkuit harus terbuka setelah beberapa kegagalan cepat dan menghentikan panggilan selama jendela cooldown singkat.
Alih-alih mengirim email secara inline, antre job "kirim struk" dengan kunci idempotensi (misalnya order_id + email_type). Jika penyedia down, antrean retry di latar dan pelanggan tetap melihat pembelian sukses.
Hasil: lebih sedikit tiket dukungan dari konfirmasi yang hilang, dan tidak ada pendapatan yang hilang karena checkout gagal karena alasan non-pembayaran.
Pilih satu alur kerja yang paling menyakitkan ketika rusak (checkout, signup, penagihan) dan jadikan referensi integrasi Anda. Lalu salin default yang sama ke mana-mana.
Urutan rollout sederhana:
Tuliskan default Anda dan jaga agar membosankan: satu connect timeout, satu request timeout, jumlah retry maksimal, rentang backoff, cooldown breaker, dan aturan untuk apa yang bisa di-retry.
Lakukan drill kegagalan sebelum memperluas ke alur berikutnya. Paksa timeout (atau blokir penyedia di lingkungan pengujian), lalu pastikan pengguna melihat pesan berguna, jalur fallback bekerja, dan retry antrean tidak menumpuk selamanya.
Jika Anda membangun produk baru dengan cepat, layak menjadikan default keandalan ini sebagai templat yang dapat dipakai ulang. Untuk tim yang menggunakan Koder.ai (koder.ai), itu sering berarti mendefinisikan timeout, retry, idempotensi, dan aturan breaker sekali, lalu menerapkan pola yang sama di layanan baru saat Anda menghasilkan dan iterasi.