Blog
Mert Özen'in yazılım geliştirme, backend, frontend ve DevOps üzerine blog yazıları.
Dış Servis Entegrasyonunun Haritası: Failure Mode'lar, Anti-Corruption Layer ve Client Seçimi (Elle, Refit, Kiota)
Dış servis entegrasyonunda ilk iş, her failure mode için beklenen davranışı yazmak ve sağlayıcının modelini ve hatalarını bir port + adapter ile kendi tiplerimize çevirmektir. Bookstore'un fake ödeme sağlayıcısı ve kargo API'si üzerinden hata modelini, ProblemDetails eşlemesini ve elle yazılmış client, Refit ve Kiota'nın şema değişikliğinde gerçekte nasıl davrandığını gösteriyoruz.
IHttpClientFactory Derinlemesine: Named, Typed ve Keyed Client'lar, Handler Ömrü ve DelegatingHandler'lar
IHttpClientFactory her CreateClient çağrısında yeni bir HttpClient döner ama handler zincirini varsayılan 2 dakika boyunca paylaştırır; .NET 9'dan beri keyed client'lar typed client'ların yerine öneriliyor. Handler ömrünü, singleton'a giren client tuzağını, handler'ın ayrı scope'unu, OAuth token cache'leyen DelegatingHandler'ı, log redaction'ı ve HttpClient.Timeout ile CancellationToken farkını gerçek çıktılarla gösteriyoruz.
Microsoft.Extensions.Http.Resilience ile Standard Pipeline: Varsayılanlar, Ayarlar ve Tuzaklar
AddStandardResilienceHandler dıştan içe rate limiter, 30 sn total timeout, 3 retry, circuit breaker ve 10 sn attempt timeout ekler; varsayılan olarak POST'u da tekrar dener ve HttpClient.Timeout'u sonsuza çeker. Bookstore'un ödeme, kargo ve kur client'ları için ayrı pipeline'ları, appsettings ile ayarı, validation kurallarını, iki handler'ın retry'ı çarpmasını ve hedging'i gerçek çıktılarla gösteriyoruz.
Polly v8 Strategy'leri Derinlemesine: Retry, Timeout, Circuit Breaker, Rate Limiter ve Fallback
Polly v8'de strategy sırası davranışı belirler: toplam timeout dışta, retry ortada, deneme timeout'u içte olmalı; MaxDelay Retry-After'ı sınırlamaz ve timeout token'ı dinlemeyen kodu durduramaz. Bookstore'da SMTP için isimli pipeline, Retry-After'a uyan retry, elle açılabilen ve health check'e bağlı circuit breaker, concurrency limiter ve kargo fiyatı için sabit tarife fallback'ini gerçek çıktılarla kuruyoruz.
Resilience'ı Test Etmek ve Gözlemlemek: WireMock.Net, Polly Chaos Strategy'leri, FakeTimeProvider ve Metric'ler
Resilience davranışı WireMock.Net ile gerçek API'ye karşı integration testlerle doğrulanır, backoff FakeTimeProvider ile beklemeden test edilir, Polly'nin chaos strategy'leri staging'de hata enjekte eder ve resilience.polly.strategy.events metric'i retry ile breaker'ı görünür kılar. Bookstore'da POST'un hiç tekrar denenmediğini, %20 hatada checkout'u ve metric'leri test ediyoruz.
Idempotent Dış Çağrılar: Idempotency-Key Göndermek, "Bilinmeyen Sonuç" ve Reconciliation
Timeout'tan sonra ödemenin alınıp alınmadığını bilemezsin; çözüm, ödeme niyeti başına bir Idempotency-Key üretip ilk istekten önce saklamak, retry'larda aynı key'i göndermek ve açık kalanları reconciliation job'uyla sağlayıcıya sormak. Bookstore'da timeout, 409 ve tekrar oynatılan yanıtı gerçek koşularla görüyoruz.
Webhook Göndermek: Standard Webhooks, İmzalama, Outbox ile Teslimat ve Retry Takvimi
Webhook'u request içinde değil outbox'tan, arka planda gönder; her isteği Standard Webhooks header'larıyla (webhook-id, webhook-timestamp, webhook-signature) HMAC-SHA256 ile imzala, günlere yayılan bir retry takvimi uygula ve hep hata veren endpoint'i kapat. Bookstore'un kurumsal müşterilerine order.shipped event'ini bu şekilde teslim ediyoruz.
Webhook Almak: İmza Doğrulama, Replay Koruması, Hızlı 2xx ve Idempotent İşleme
Gelen webhook'un imzasını model binding'den önce ham gövde üzerinden ve sabit süreli karşılaştırmayla doğrula, timestamp toleransı ve webhook-id ile replay'i engelle, event'i inbox'a yazıp hemen 200 dön ve işlemeyi arka planda idempotent yap. Bookstore'da payment.succeeded ile bilinmeyen ödeme sonuçlarını kapatıyoruz.
HttpClient ve Resilience'ta Sürümlerle Gelenler: Microsoft.Extensions.Http.Polly'den Http.Resilience'a, Polly v7'den v8'e ve .NET 11
Microsoft.Extensions.Http.Polly'nin yerini Microsoft.Extensions.Http.Resilience aldı ve Polly v8'de policy'ler tek bir ResiliencePipeline'a dönüştü; eski kod AsAsyncPolicy köprüsüyle adım adım taşınabilir. .NET 11 de request compression, deneysel bir connection eviction callback'i ve tipli DNS kayıtları getiriyor.