Resolver GraphQL yang memanggil webhook microservice sering menjadi titik rawan timeout. Dalam 1–2 paragraf ini kita lihat gejala spesifiknya: permintaan GraphQL tidak selesai, client menerima timeout, dan log resolver memperlihatkan pemanggilan webhook yang menunggu terlalu lama. Pendekatan debugging langsung adalah memahami apakah timeout berasal dari loop retry, pemrosesan batch, atau kurangnya visibilitas pada alur asynchronous resolver.

Memahami Gejala Timeout Resolver

Timeout resolver terlihat sebagai request GraphQL yang tidak menyelesaikan sebelum batas waktu gateway (biasanya 5–10 detik). Di log, akan terlihat: resolver memanggil webhook dan tidak kembali, kadang diikuti log retry tanpa respons berhasil. Interaksi ini bisa dipicu oleh webhook yang lambat, tapi terlalu sering bottleneck adalah pola internal resolver.

Menelusuri Alur Resolver ke Webhook

Mulailah dari resolver yang mengeksekusi handler webhook. Jika resolver memanggil beberapa microservice secara paralel, catat urutan pemanggilan, timeout default, dan waktu tunggu total sebelum response dikirim kembali ke gateway. Buat diagram sederhana dari GraphQL field hingga outbound webhook untuk memetakan setiap titik delay.

Mengevaluasi Penyebab Utama

Loop Retry Tak Terkontrol

Resolver kadang membungkus pemanggilan webhook dengan retry otomatis (baik manual maupun library). Jika webhook mengalami latensi sementara, retry cepat dapat menciptakan loop yang memblok resolver. Akibatnya, resolver terus menunggu sampai retry melebihi timeout gateway. Periksa apakah factory HTTP client menggunakan retry tanpa backoff atau tanpa batas maksimum, dan pastikan retry tidak dipicu di level resolver saat sudah ada mekanisme gateway.

Pemrosesan Batch dan Penundaan

Resolver yang memanggil webhook dalam batch (misalnya mengumpulkan 50 event dan memanggil satu endpoint sekaligus) bisa membuat satu request menunggu batch selesai. Jika batch menunggu data dari sub-resolver lain atau queue, timeout akan muncul meski webhook sebenarnya cepat. Analisis apakah resolver menunggu Promise.all atau mekanisme aggregation lain; pertimbangkan membagi batch menjadi panggilan independen atau memperpendek batch window agar tidak menunggu terlalu lama.

Keterbatasan Observabilitas

Tanpa metrik atau tracing, sulit menentukan apakah timeout terjadi di resolver, network, atau webhook. Banyak penerapan hanya menampilkan error "GraphQL timeout" tanpa konteks. Gunakan tracing terdistribusi (contoh: OpenTelemetry) untuk melihat waktu yang dihabiskan di resolver, waktu tunggu HTTP client, dan respons microservice. Tanpa visibilitas, eksperimen blind mencoba-coba-konfigurasi justru menunda perbaikan.

Langkah Perbaikan Praktis

Monitoring dan Tracing

  • Catat waktu mulai dan selesai resolver di log, sertakan trace ID jika ada tracing.
  • Tingkatkan metrik seperti resolver_duration_ms dan webhook_latency_ms.
  • Gunakan distributed tracing untuk menghubungkan request GraphQL dengan outbound webhook.

Pengaturan Timeout dan Retries

Mengatur timeout khusus HTTP client memastikan resolver tidak menunggu selamanya. Contoh berikut menunjukkan pola timeout dengan pembatalan (JavaScript/Node.js):

const controller = new AbortController();
const timeoutMs = 4000;
const timeout = setTimeout(() => controller.abort(), timeoutMs);
try {
  const response = await fetch(webhookUrl, {
    method: 'POST',
    body: JSON.stringify(payload),
    signal: controller.signal,
  });
  if (!response.ok) throw new Error('Webhook error');
  return await response.json();
} finally {
  clearTimeout(timeout);
}

Sesuaikan timeout dengan SLA gateway dan pastikan webhook memiliki batas lebih rendah dari overall resolver timeout. Hindari retry agresif: gunakan retry terbatas dengan exponential backoff dan hanya pada status yang layak (misalnya 5xx, bukan 4xx).

Isolasi Transaksi Webhook

Untuk menghindari satu resolver memblokir seluruh operasi, isolasi pemanggilan webhook di worker terpisah atau gunakan pola publish/subscribe untuk menjalankan sisi efek. Resolver dapat langsung mengembalikan status "pending" kepada client sementara webhook dieksekusi asinkron secara independen. Jika perlu hasil synchronus, pastikan webhook memiliki circuit breaker dan fallback agar tidak mempengaruhi field lain dalam query.

Kesimpulan

Timeout resolver GraphQL saat memanggil webhook microservice biasanya berasal dari kombinasi retry tak terkendali, batch panjang, dan kurangnya observabilitas. Dengan memetakan alur, mengatur timeout dan retry secara sadar, serta menambahkan monitoring/tracing, Anda mengendalikan timeout tersebut. Selalu pertimbangkan trade-off: timeout terlalu singkat memutus proses sah, sementara terlalu panjang menahan resource.