IHttpClientFactory: avoids the socket exhaustion of new HttpClient() on every call.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // ====================================================================== // Q: How do you call a flaky third-party HTTP API? // // - IHttpClientFactory: avoids the socket exhaustion of new HttpClient() on // every call. // - Retry only on transient errors (5xx, 408, 429) and only on idempotent calls. // A POST without an idempotency key is not retried blindly. // - Circuit breaker, so we don't overwhelm an ERP that is already struggling. // - A typed client with our own DTOs = anti-corruption layer: the ERP's model // does not leak into our domain. // ====================================================================== builder.Services.AddHttpClient<IErpClient, ErpClient>(c => { c.BaseAddress = new Uri(builder.Configuration["Erp:BaseUrl"]!); c.Timeout = Timeout.InfiniteTimeSpan; // the timeout is controlled by the resilience pipeline }) .AddStandardResilienceHandler(o => // Microsoft.Extensions.Http.Resilience (Polly v8) { o.Retry.MaxRetryAttempts = 3; o.Retry.UseJitter = true; o.AttemptTimeout.Timeout = TimeSpan.FromSeconds(10); o.CircuitBreaker.SamplingDuration = TimeSpan.FromSeconds(30); }); |