Lewati ke konten utama
Didit Raih $7,5 Juta untuk Membangun Infrastruktur Identitas dan Fraud
Didit
Kembali ke blog
Blog · 6 Maret 2026

Menguasai Penanganan Kesalahan & Percobaan Ulang API Didit di Go (ID)

Membangun integrasi yang kuat dengan API Didit di Go memerlukan strategi penanganan kesalahan dan percobaan ulang yang canggih. Panduan ini membahas praktik terbaik, mulai dari memahami batas laju dan kode kesalahan khusus Didit.

Oleh DiditDiperbarui
didit-api-error-handling-retries-go.png

Pahami Batas Laju DiditTerapkan pembatasan sisi klien dan exponential backoff untuk respons 429, gunakan header X-RateLimit-Limit, X-RateLimit-Remaining, dan X-RateLimit-Reset untuk mencegah gangguan layanan.

Bedakan Jenis KesalahanBedakan antara kesalahan sementara (misalnya, masalah jaringan, ketidaktersediaan layanan) dan kesalahan permanen (misalnya, kunci API tidak valid, permintaan yang salah) untuk menerapkan logika percobaan ulang yang sesuai atau gagal dengan cepat.

Terapkan Mekanisme Percobaan Ulang yang KuatGunakan loop percobaan ulang terstruktur dengan exponential backoff, jitter, dan upaya percobaan ulang maksimum untuk menangani kegagalan sementara dengan anggun, meningkatkan keandalan operasi penting seperti pembuatan sesi.

Pendekatan Mengutamakan Pengembang Didit Menyederhanakan IntegrasiDidit menyediakan dokumentasi API yang jelas, header batas laju spesifik, dan arsitektur modular, memungkinkan pengembang Go untuk membangun alur verifikasi identitas yang tangguh dengan mudah dan percaya diri.

Mengintegrasikan API pihak ketiga adalah landasan pengembangan aplikasi modern, dan verifikasi identitas tidak terkecuali. Saat bekerja dengan layanan penting seperti platform identitas Didit, memastikan integrasi Anda tangguh terhadap fluktuasi jaringan, gangguan layanan, dan batas laju adalah hal yang terpenting. Panduan ini membahas penanganan kesalahan tingkat lanjut dan strategi percobaan ulang yang secara khusus disesuaikan untuk integrasi API Didit menggunakan Go, membantu Anda membangun sistem yang kuat dan andal.

Memahami Lanskap Kesalahan API Didit

Sebelum menerapkan logika percobaan ulang apa pun, penting untuk memahami jenis kesalahan yang mungkin Anda temui. API Didit, seperti banyak layanan yang dirancang dengan baik, mengomunikasikan berbagai status melalui kode status HTTP. Meskipun kode 2xx standar menunjukkan keberhasilan, Anda akan fokus terutama pada 4xx (kesalahan klien) dan 5xx (kesalahan server), dan terutama 429 (Terlalu Banyak Permintaan).

Pembatasan Laju Didit dan Artinya bagi Anda

Didit memberlakukan pembatasan laju untuk menjaga stabilitas API. Ini adalah aspek penting untuk dikelola dalam integrasi Anda. Misalnya, endpoint GET biasanya memiliki batas global 300 permintaan per menit per aplikasi, dengan endpoint spesifik seperti session-decision (100 rpm) atau session-v2-create (600 rpm) memiliki batasnya sendiri yang berpotensi lebih ketat. Saat Anda mencapai batas laju, Didit merespons dengan kode status 429 Too Many Requests dan menyertakan header yang membantu:

  • X-RateLimit-Limit: Jumlah maksimum permintaan yang diizinkan dalam jendela saat ini.
  • X-RateLimit-Remaining: Jumlah permintaan yang tersisa dalam jendela saat ini.
  • X-RateLimit-Reset: Waktu (dalam detik epoch) ketika jendela batas laju saat ini direset.
  • Retry-After: (Sering disertakan) Jumlah detik untuk menunggu sebelum membuat permintaan lain.

Klien Go Anda harus secara aktif memantau header ini. Ketika X-RateLimit-Remaining turun di bawah ambang batas tertentu (misalnya, 15% dari X-RateLimit-Limit), Anda harus secara proaktif membatasi permintaan Anda. Mengabaikan ini dapat menyebabkan kesalahan 429 yang berkelanjutan, memengaruhi kemampuan aplikasi Anda untuk membuat sesi verifikasi atau mengambil hasil dari produk seperti Verifikasi ID atau Penyaringan AML Didit.

Menerapkan Strategi Percobaan Ulang yang Kuat dengan Exponential Backoff di Go

Untuk kesalahan sementara (misalnya, batas waktu jaringan, ketidaktersediaan layanan sementara, atau 429), percobaan ulang sangat penting. Namun, percobaan ulang yang naif dapat memperburuk masalah. Standar emas adalah exponential backoff dengan jitter.

Exponential Backoff dengan Jitter

Exponential backoff berarti meningkatkan waktu tunggu antar percobaan ulang secara eksponensial. Jitter (menambahkan penundaan acak kecil) mencegah masalah 'thundering herd' di mana banyak klien mencoba ulang secara bersamaan setelah pemadaman, membanjiri layanan lagi. Berikut adalah contoh konseptual Go:

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"time"
	"math/rand"
)

func callDiditAPIWithRetry(url string, maxRetries int) ([]byte, error) {
	client := &http.Client{Timeout: 10 * time.Second}
	rand.Seed(time.Now().UnixNano())

	for i := 0; i <= maxRetries; i++ {
		resp, err := client.Get(url)
		if err != nil {
			// Handle network errors (e.g., connection refused, timeout)
			fmt.Printf("Attempt %d: Network error: %v\n", i+1, err)
			if i == maxRetries {
				return nil, fmt.Errorf("failed after %d retries: %w", maxRetries, err)
			}
			sleepTime := time.Duration(1<<i)*time.Second + time.Duration(rand.Intn(1000))*time.Millisecond // Exponential backoff + jitter
			fmt.Printf("Retrying in %v...\n", sleepTime)
			time.Sleep(sleepTime)
			continue
		}
		defer resp.Body.Close()

		switch resp.StatusCode {
		case http.StatusOK:
			fmt.Printf("Attempt %d: Success!\n", i+1)
			return ioutil.ReadAll(resp.Body)
		case http.StatusTooManyRequests:
			// Respect Retry-After header if present
			retryAfter := resp.Header.Get("Retry-After")
			if retryAfter != "" {
				if sleepSeconds, err := time.ParseDuration(retryAfter + "s"); err == nil {
					fmt.Printf("Attempt %d: Rate limited. Retrying after %v.\n", i+1, sleepSeconds)
					time.Sleep(sleepSeconds)
					continue
				}
			}
			// Fallback to exponential backoff if Retry-After is missing or invalid
			fmt.Printf("Attempt %d: Rate limited (429).\n", i+1)
			if i == maxRetries {
				return nil, fmt.Errorf("rate limited after %d retries", maxRetries)
			}
			sleepTime := time.Duration(1<<i)*time.Second + time.Duration(rand.Intn(1000))*time.Millisecond
			fmt.Printf("Retrying in %v...\n", sleepTime)
			time.Sleep(sleepTime)
			continue
		case http.StatusInternalServerError, http.StatusBadGateway, http.StatusServiceUnavailable, http.StatusGatewayTimeout:
			// Server-side errors that might be transient
			fmt.Printf("Attempt %d: Server error %d. Retrying.\n", i+1, resp.StatusCode)
			if i == maxRetries {
				return nil, fmt.Errorf("server error %d after %d retries", resp.StatusCode, maxRetries)
			}
			sleepTime := time.Duration(1<<i)*time.Second + time.Duration(rand.Intn(1000))*time.Millisecond
			fmt.Printf("Retrying in %v...\n", sleepTime)
			time.Sleep(sleepTime)
			continue
		default:
			// Non-retryable errors (4xx client errors, etc.)
			body, _ := ioutil.ReadAll(resp.Body)
			return nil, fmt.Errorf("non-retryable API error: %d %s, response: %s", resp.StatusCode, resp.Status, string(body))
		}
	}
	return nil, fmt.Errorf("unexpected control flow") // Should not be reached
}

func main() {
	// Example usage: Replace with actual Didit API endpoint
	// For a real integration, you'd be POSTing to /v3/session/ or similar
	// and handling the verification_url.
	apiURL := "https://verification.didit.me/health"
	data, err := callDiditAPIWithRetry(apiURL, 5)
	if err != nil {
		fmt.Println("Failed to call API:", err)
	} else {
		fmt.Println("API Response:", string(data))
	}
}

Cuplikan ini menunjukkan cara menangani kesalahan jaringan, 429 (menghormati Retry-After), dan kesalahan 5xx umum dengan exponential backoff dan jitter. Ini juga menunjukkan kegagalan cepat untuk kesalahan 4xx yang tidak dapat dicoba ulang, yang biasanya disebabkan oleh input yang salah dan tidak akan terselesaikan saat dicoba ulang. Ini sangat penting untuk operasi seperti membuat sesi verifikasi menggunakan arsitektur modular Didit.

Menerapkan Pola Circuit Breaker

Meskipun percobaan ulang membantu mengatasi masalah sementara, terus-menerus mencoba ulang layanan yang gagal dapat membebani lebih lanjut atau membuang sumber daya jika layanan benar-benar mati. Di sinilah pola circuit breaker berperan. Circuit breaker memantau kegagalan dan, jika mencapai ambang batas tertentu, "membuka" sirkuit, mencegah permintaan lebih lanjut untuk periode waktu tertentu. Setelah periode tersebut, ia mengizinkan beberapa permintaan uji untuk melihat apakah layanan telah pulih.

Di Go, Anda dapat menggunakan pustaka seperti sony/gobreaker untuk menerapkan pola ini:

package main

import (
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"time"

	"github.com/sony/gobreaker"
)

var cb *gobreaker.CircuitBreaker

func init() {
	st := gobreaker.Settings{
		Name:        "DiditAPICircuitBreaker",
		MaxRequests: 3, // Allow 3 requests in half-open state
		Interval:    5 * time.Second, // Period to collect data for trip decisions
		Timeout:     10 * time.Second, // Open circuit for 10 seconds
		ReadyToTrip: func(counts gobreaker.Counts) bool {
			return counts.ConsecutiveFailures > 5 // Trip after 5 consecutive failures
		},
		OnStateChange: func(name string, from gobreaker.State, to gobreaker.State) {
			fmt.Printf("Circuit Breaker '%s' changed from %s to %s\n", name, from, to)
		},
	}
	cb = gobreaker.NewCircuitBreaker(st)
}

func callDiditAPIWithCircuitBreaker(url string) ([]byte, error) {
	body, err := cb.Execute(func() (interface{}, error) {
		resp, err := http.Get(url)
		if err != nil {
			return nil, err // Network error
		}
		defer resp.Body.Close()

		if resp.StatusCode != http.StatusOK {
			// Only count 5xx and 429 as failures for circuit breaker
			if resp.StatusCode == http.StatusTooManyRequests || resp.StatusCode >= http.StatusInternalServerError {
				return nil, fmt.Errorf("API returned status %d", resp.StatusCode)
			}
			// For other 4xx errors, we might not want to trip the breaker, but still return an error
			bodyBytes, _ := ioutil.ReadAll(resp.Body)
			return nil, fmt.Errorf("non-retryable API error: %d %s, response: %s", resp.StatusCode, resp.Status, string(bodyBytes))
		}

		return ioutil.ReadAll(resp.Body)
	})

	if err != nil {
		if errors.Is(err, gobreaker.ErrOpenState) {
			return nil, fmt.Errorf("circuit breaker is open: %w", err)
		}
		return nil, err
	}

	return body.([]byte), nil
}

func main() {
	// Example usage
	apiURL := "https://verification.didit.me/health"
	for i := 0; i < 10; i++ {
		data, err := callDiditAPIWithCircuitBreaker(apiURL)
		if err != nil {
			fmt.Printf("Call %d failed: %v\n", i+1, err)
		} else {
			fmt.Printf("Call %d successful: %s\n", i+1, string(data))
		}
		time.Sleep(1 * time.Second)
	}
}

Menggabungkan circuit breaker dengan exponential backoff memastikan bahwa aplikasi Anda tetap responsif dan tidak membebani layanan eksternal yang sedang bermasalah. Ini sangat penting saat menangani permintaan verifikasi identitas bervolume tinggi, seperti yang melibatkan Verifikasi ID Didit atau pemeriksaan Liveness Pasif & Aktif.

Menangani Kegagalan Webhook dan Hasil Asinkron

API Didit sering kali memberikan hasil secara asinkron melalui webhook, misalnya, setelah pengguna menyelesaikan alur verifikasi ID atau ketika pemeriksaan Penyaringan AML selesai. Endpoint webhook Anda harus tangguh. Jika endpoint Anda gagal memproses webhook (misalnya, mengembalikan kode status 5xx), Didit akan mencoba ulang pengiriman webhook. Sangat penting untuk:

  • Segera Mengakui Penerimaan: Kembalikan kode status 2xx secepat mungkin untuk menandakan penerimaan yang berhasil, meskipun pemrosesan membutuhkan waktu lebih lama.
  • Proses Secara Asinkron: Serahkan payload webhook ke pekerja latar belakang atau antrean pesan (misalnya, Kafka, RabbitMQ) untuk diproses. Ini mencegah endpoint webhook Anda kehabisan waktu percobaan ulang Didit.
  • Idempotensi: Pastikan logika pemrosesan webhook Anda idempoten. Jika Didit mencoba ulang dan mengirimkan webhook yang sama beberapa kali, sistem Anda harus memprosesnya hanya sekali untuk menghindari tindakan duplikat atau inkonsistensi data.
  • Verifikasi Tanda Tangan: Selalu verifikasi tanda tangan webhook menggunakan Webhook Secret Key Anda dari Didit Console untuk memastikan permintaan benar-benar berasal dari Didit dan belum dirusak.

Bagaimana Didit Membantu

Didit dirancang dengan pengalaman pengembang dan keandalan dalam pikiran, menyediakan fitur-fitur yang secara inheren menyederhanakan penanganan kesalahan tingkat lanjut dan strategi percobaan ulang untuk integrasi Go Anda. Pendekatan mengutamakan pengembang kami berarti dokumentasi API yang jelas, komprehensif, kotak pasir instan, dan API yang bersih yang membuat integrasi menjadi mudah.

  • Pembatasan Laju yang Dapat Diprediksi: Didit dengan jelas mendefinisikan batas laju global dan spesifik endpoint, bersama dengan header HTTP standar (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, Retry-After) untuk memandu pembatasan sisi klien dan logika backoff Anda. Transparansi ini memberdayakan Anda untuk membangun mekanisme percobaan ulang yang dioptimalkan untuk layanan seperti Verifikasi ID dan Penyaringan AML.
  • Arsitektur Modular: Primitif identitas modular kami berarti Anda dapat membangun alur kerja yang tangguh berdasarkan desain. Jika satu pemeriksaan spesifik (misalnya, Bukti Alamat) mengalami masalah sementara, alur kerja keseluruhan Anda dapat dikonfigurasi untuk beradaptasi atau mencoba ulang komponen tertentu tanpa memengaruhi langkah-langkah verifikasi yang tidak terkait.
  • Keandalan AI-Native: Backend Didit yang AI-native dibangun untuk skala dan ketahanan, meminimalkan kesalahan sisi server yang akan Anda temui. Ini memungkinkan Anda untuk memfokuskan penanganan kesalahan Anda pada masalah jaringan dan sisi klien, daripada pemadaman layanan yang konstan.
  • KYC Inti Gratis & Harga Fleksibel: Mulai dengan tingkat gratis Didit untuk KYC Inti, memungkinkan Anda untuk menguji penanganan kesalahan dan strategi percobaan ulang Anda secara menyeluruh di lingkungan seperti produksi tanpa biaya di muka. Model pembayaran per-pemeriksaan-berhasil kami lebih lanjut menyelaraskan keberhasilan kami dengan keberhasilan Anda.

Siap Memulai?

Siap melihat Didit beraksi? Dapatkan demo gratis hari ini.

Mulai verifikasi identitas secara gratis dengan tingkat gratis Didit.

Infrastruktur untuk identitas dan fraud.

Satu API untuk KYC, KYB, Transaction Monitoring, dan Wallet Screening. Integrasi dalam 5 menit.

Minta AI untuk merangkum halaman ini
Penanganan Error & Retri API Didit di Go: Pendalaman.