Go Fiber: Kontrak Auth Token dan Retry Webhook Internal menangani dua tantangan utama integrasi antar layanan—membuat webhook internal aman dan toleran terhadap retry. Artikel ini langsung menjelaskan bagaimana menyusun header otentikasi, memastikan idempoten, serta mengatur retry/backoff agar tidak ada duplikat dan tidak melampaui rate limit.
Desain Kontrak Auth Token untuk Webhook Internal
Kontrak webhook internal perlu menetapkan nilai header minimal: token, scope layanan, dan kadaluarsa agar penerima dapat memvalidasi permintaan tanpa mengandalkan database eksternal di jalur utama. Contoh header yang digunakan:
- Authorization: Bearer token-jwt dengan klaim
scope:webhook:internaldanexp. - X-Webhook-Origin: nama layanan pemanggil untuk audit.
- X-Idempotency-Key: UUID untuk deduplikasi.
Middleware Fiber berikut memeriksa header dan memvalidasi scope serta expiry sebelum menjalankan handler:
func authMiddleware(c *fiber.Ctx) error {
token := strings.TrimPrefix(c.Get("Authorization"), "Bearer ")
claims, err := validateToken(token)
if err != nil || !claims.Scope.Contains("webhook:internal") {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "invalid token"})
}
if time.Until(time.Unix(claims.ExpiresAt, 0)) < 0 {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "token expired"})
}
c.Locals("origin", c.Get("X-Webhook-Origin"))
return c.Next()
}
Validasi token bisa dilakukan via JWT, HMAC, atau shared secret tergantung arsitektur. Pastikan layanan penerima hanya menerima scope yang sudah disepakati agar tidak menyala untuk permintaan umum.
Menjaga Idempoten dan Retry pada Handler Fiber
Handler webhook harus memperhatikan X-Idempotency-Key untuk deduplikasi. Implementasi sederhana dapat memakai cache Redis dengan TTL minimal sama dengan window ulang guna menyaring permintaan duplikat.
func webhookHandler(c *fiber.Ctx) error {
idempotencyKey := c.Get("X-Idempotency-Key")
if idempotencyKey == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "missing idempotency key"})
}
if seen, _ := cache.SetNX(idempotencyKey, "processing", time.Minute*5); !seen {
return c.Status(fiber.StatusConflict).JSON(fiber.Map{"error": "duplicate request"})
}
defer cache.Del(idempotencyKey)
// proses payload
return c.SendStatus(fiber.StatusOK)
}
Pemanfaatan SetNX (set if not exists) mencegah eksekusi ganda saat klien mengirim ulang sebelum status sebelumnya terselesaikan. TTL memastikan key otomatis dibersihkan walau terjadi failure.
Batas Retry dan Backoff
Untuk menghindari rate limit dan duplikat, tetapkan protokol retry di sisi pemanggil dan penerima:
- Biarkan pengirim menerapkan retry terbatas (misalnya maksimal 3 percobaan) dengan exponential backoff dan jitter.
- Penerima memeriksa header
Retry-Attemptatau log internal untuk memutuskan ketika sistem sedang dibanjiri. - Jika beban tinggi, tanggapi dengan
429 Too Many Requestsdan headerRetry-Afteragar pengirim menunda pengiriman selanjutnya.
Dengan pendekatan ini, penerima tetap memberi sinyal yang jelas dan kontrol terhadap retry rate, sementara deduplikasi menghindari efek samping ganda seperti pembayaran ganda atau pengiriman notifikasi berulang.
Rute Go Fiber dan Middleware Terintegrasi
Untuk merangkai semuanya, register middleware dan handler di Fiber:
app := fiber.New()
app.Use(authMiddleware)
app.Post("/internal/webhook", webhookHandler)
app.Listen(":8080")
Pastikan router tidak mengekspos endpoint ini ke publik. Gunakan network policy atau sidecar firewall agar hanya layanan internal yang bisa mencapai URL tersebut.
Observability untuk Kontrak Webhook
Tanpa visibilitas, debugging webhook internal sulit. Fokus observability pada tiga aspek:
- Log: Catat nilai header penting (origin, idempotency key, retry attempt) serta alasan kenapa request ditolak (expired token, duplicate).
- Metric: Buat histogram latency, counter status code, dan hitungan deduplikasi untuk memantau efektivitas retry.
- Dead-letter: Jika handler gagal setelah retry terbatas, kirim payload ke dead-letter queue (misalnya Kafka topic atau database terpisah) agar tim dapat menyelidiki tanpa kehilangan data.
Log yang terstruktur memudahkan korelasi dengan trace ID atau request ID. Metric memberi tanda awal bahwa retry meningkat, sementara dead-letter memberikan mekanisme recovery tanpa memblokir retry otomatis.
Pertimbangan dan Kesalahan Umum
Perhatikan trade-off berikut:
- TTL idempotency key terlalu pendek bisa menyebabkan duplikat jika retry lama. Terlalu panjang bisa menyumbat cache.
- Jika token hanya berlaku pendek, pastikan sinkronisasi waktu antar layanan agar tidak salah menolak permintaan valid.
- Jangan abaikan kemungkinkan payload di-retry dari jaringan yang berbeda; selalu verifikasi idempotency key di setiap request.
Debugging tips: gunakan fiber.Ctx.Locals untuk membawa metadata dari middleware ke handler; tambahkan trace ID untuk memudahkan pencarian di log.
Dengan kontrak token yang jelas, mekanisme idempoten, retry/backoff terkontrol, serta observability yang matang, webhook internal Go Fiber bisa berjalan andal tanpa menyebabkan gangguan cascading pada layanan lain.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!