A resilient HTTP client for .NET 6+ with retry, caching, rate limiting,
circuit breaker, bulkhead isolation, fallback routing, telemetry, and request signing.
dotnet add package Kaz.HttpInstall-Package Kaz.Http| Feature | Description |
|---|---|
| Retry | Automatic retry with exponential backoff and 429 Retry-After support |
| Caching | ETag-based response caching with deduplication of concurrent GET requests |
| Rate Limiting | Per-host request rate limiting with configurable window |
| Circuit Breaker | Prevents cascading failures with configurable threshold and recovery timeout |
| Bulkhead | Limits concurrent requests per host via semaphore isolation |
| Fallback Routing | Redirects to a backup URL when the primary fails after all retries |
| Request Signing | Adds HMAC-SHA256 X-Timestamp and X-Signature headers |
| Contracts | Post-deserialization response validation with custom rules |
| Telemetry | Tracks total requests, errors, and last request duration |
GET
var response = await Client.GetAsync<WeatherData>("https://api.example.com/weather");
if (response.IsSuccess)
Console.WriteLine(response.Data);
// Authenticated
var response = await Client.GetAsync<WeatherData>("https://api.example.com/weather", apiKey);POST
var response = await Client.PostAsync<CreateUserRequest, UserResponse>(
"https://api.example.com/users",
new CreateUserRequest { Name = "Alice" });
// Authenticated
var response = await Client.PostAsync<CreateUserRequest, UserResponse>(
"https://api.example.com/users", apiKey,
new CreateUserRequest { Name = "Alice" });PUT
var response = await Client.PutAsync<UpdateUserRequest, UserResponse>(
"https://api.example.com/users/1",
new UpdateUserRequest { Name = "Bob" });PATCH
var response = await Client.PatchAsync<PatchRequest, UserResponse>(
"https://api.example.com/users/1",
new PatchRequest { Name = "Bob" });DELETE
var response = await Client.DeleteAsync<DeleteResponse>("https://api.example.com/users/1");HEAD
// Returns headers only — no body is read
var response = await Client.HeadAsync<object>("https://api.example.com/users");
if (response.IsSuccess)
Console.WriteLine(response.Headers);Retry
Client.RetryCount = 3; // default: 3
Client.RetryDelay = 1000; // initial delay in ms, doubles on each retry (default: 1000)Circuit Breaker
Client.CircuitBreakerFailureThreshold = 3; // default: 3
Client.CircuitBreakerRecoveryTimeout = TimeSpan.FromSeconds(30); // default: 30sRate Limiting
Client.RateLimiterMaxRequests = 100; // default: 100
Client.RateLimiterPeriod = TimeSpan.FromSeconds(1); // default: 1sTimeout
Client.SetTimeout("https://api.example.com", TimeSpan.FromSeconds(10));Bulkhead
Client.SetBulkhead("https://api.example.com", maxConcurrent: 5);Fallback URL
Client.RegisterFallbackUrl(
"https://api.example.com/data",
"https://backup.example.com/data");Request Signing
Client.SigningKey = "your-secret-key";Response Contracts
Client.AddContract<UserResponse>(user =>
user.Id > 0 ? null : "Invalid user ID.");Default Headers
Client.AddDefaultHeader("X-App-Version", "2.0.0");Telemetry
Console.WriteLine(Client.Telemetry.TotalRequests); // total requests sent
Console.WriteLine(Client.Telemetry.Errors); // total failed requests
Console.WriteLine(Client.Telemetry.Duration); // last request duration in msThis project is distributed under the MIT License — free for personal and commercial use.
If you want to contact me about the NuGet package, collaboration, or any development-related questions, feel free to reach out through the links below: