Reliable.HttpClient.Caching 1.0.0-alpha1

This is a prerelease version of Reliable.HttpClient.Caching.
There is a newer version of this package available.
See the version list below for details.
dotnet add package Reliable.HttpClient.Caching --version 1.0.0-alpha1
                    
NuGet\Install-Package Reliable.HttpClient.Caching -Version 1.0.0-alpha1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Reliable.HttpClient.Caching" Version="1.0.0-alpha1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Reliable.HttpClient.Caching" Version="1.0.0-alpha1" />
                    
Directory.Packages.props
<PackageReference Include="Reliable.HttpClient.Caching" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Reliable.HttpClient.Caching --version 1.0.0-alpha1
                    
#r "nuget: Reliable.HttpClient.Caching, 1.0.0-alpha1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Reliable.HttpClient.Caching@1.0.0-alpha1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Reliable.HttpClient.Caching&version=1.0.0-alpha1&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Reliable.HttpClient.Caching&version=1.0.0-alpha1&prerelease
                    
Install as a Cake Tool

Reliable.HttpClient.Caching

NuGet Version

Caching extensions for Reliable.HttpClient with support for memory cache and custom cache providers.

Features

  • Automatic HTTP Response Caching – Cache responses based on configurable rules
  • Multiple Cache Providers – Memory cache and custom cache providers support
  • Flexible Configuration – TTL, cache keys, status codes, HTTP methods
  • Smart Cache Keys – Automatic generation based on request method, URI, and headers
  • Cache Management – Manual cache invalidation and clearing
  • Logging Support – Built-in logging for cache hits/misses

Installation

dotnet add package Reliable.HttpClient.Caching

Quick Start

Basic Memory Caching

// Registration - Method 1: Separate registration (recommended)
services.AddMemoryCache();  // Required for memory caching
services.AddHttpClient<WeatherApiClient>()
    .AddResilience();  // From Reliable.HttpClient

services.AddHttpClientCaching<WeatherApiClient, WeatherResponse>(options =>
{
    options.DefaultExpiry = TimeSpan.FromMinutes(5);
    options.MaxCacheSize = 1_000;
});

// Registration - Method 2: Fluent API (alternative)
services.AddHttpClient<WeatherApiClient>()
    .AddResilience()  // From Reliable.HttpClient
    .AddMemoryCache<WeatherResponse>(options =>
    {
        options.DefaultExpiry = TimeSpan.FromMinutes(5);
        options.MaxCacheSize = 1_000;
    });

// Usage
public class WeatherService
{
    private readonly CachedHttpClient<WeatherResponse> _client;

    public WeatherService(CachedHttpClient<WeatherResponse> client)
    {
        _client = client;
    }

    public async Task<WeatherResponse> GetWeatherAsync(string city)
    {
        return await _client.GetFromJsonAsync($"/weather?city={city}");
        // First call hits API, subsequent calls return cached response
    }
}

Advanced Configuration

services.AddMemoryCache();  // Required
services.AddHttpClient<ApiClient>()
    .AddResilience();  // Optional: add resilience policies

services.AddHttpClientCaching<ApiClient, ApiResponse>(options =>
{
    options.DefaultExpiry = TimeSpan.FromMinutes(10);

    // Custom cache key generation
    options.KeyGenerator = new CustomCacheKeyGenerator();

    // Only cache successful responses
    options.ShouldCache = (request, response) =>
        response.IsSuccessStatusCode &&
        !request.Headers.Authorization?.Parameter?.Contains("temp");

    // Custom expiry based on response
    options.GetExpiry = (request, response) =>
    {
        if (response.Headers.CacheControl?.MaxAge.HasValue == true)
            return response.Headers.CacheControl.MaxAge.Value;
        return TimeSpan.FromMinutes(5);
    };

    // Cache only specific methods and status codes
    options.CacheableMethods = new HashSet<HttpMethod> { HttpMethod.Get };
    options.CacheableStatusCodes = new HashSet<HttpStatusCode>
    {
        HttpStatusCode.OK,
        HttpStatusCode.NotModified
    };
});

Manual Cache Operations

public class ApiService
{
    private readonly CachedHttpClient<ApiResponse> _client;

    public async Task<ApiResponse> GetDataAsync(string id)
    {
        var request = new HttpRequestMessage(HttpMethod.Get, $"/api/data/{id}");

        return await _client.SendAsync(request, async response =>
        {
            response.EnsureSuccessStatusCode();
            var json = await response.Content.ReadAsStringAsync();
            return JsonSerializer.Deserialize<ApiResponse>(json);
        });
    }

    public async Task InvalidateDataAsync(string id)
    {
        var request = new HttpRequestMessage(HttpMethod.Get, $"/api/data/{id}");
        await _client.RemoveFromCacheAsync(request);
    }

    public async Task ClearAllCacheAsync()
    {
        await _client.ClearCacheAsync();
    }
}

Custom Cache Provider

public class RedisCacheProvider<TResponse> : IHttpResponseCache<TResponse>
{
    private readonly IDatabase _database;

    public async Task<TResponse?> GetAsync(string key, CancellationToken cancellationToken = default)
    {
        var value = await _database.StringGetAsync(key);
        return value.HasValue ? JsonSerializer.Deserialize<TResponse>(value) : default;
    }

    public async Task SetAsync(string key, TResponse value, TimeSpan? expiry = null, CancellationToken cancellationToken = default)
    {
        var json = JsonSerializer.Serialize(value);
        await _database.StringSetAsync(key, json, expiry);
    }

    // ... implement other methods
}

// Registration
services.AddMemoryCache();  // Still required for fallback
services.AddHttpClient<ApiClient>();

// Option 1: Using AddHttpClientCaching with custom provider
services.AddScoped<IHttpResponseCache<ApiResponse>, RedisCacheProvider<ApiResponse>>();
services.AddHttpClientCaching<ApiClient, ApiResponse>();

// Option 2: Using fluent API (if available)
services.AddHttpClient<ApiClient>()
    .AddCache<ApiResponse, RedisCacheProvider<ApiResponse>>();

Configuration Options

Property Type Default Description
DefaultExpiry TimeSpan 5 minutes Default cache expiration time
MaxCacheSize int? 1_000 Maximum cached items (memory cache only)
KeyGenerator ICacheKeyGenerator DefaultCacheKeyGenerator Cache key generation strategy
CacheableStatusCodes HashSet<HttpStatusCode> 200, 304, 206 HTTP status codes to cache
CacheableMethods HashSet<HttpMethod> GET, HEAD HTTP methods to cache
ShouldCache Func<HttpRequestMessage, HttpResponseMessage, bool> Cache-Control aware Custom caching logic
GetExpiry Func<HttpRequestMessage, HttpResponseMessage, TimeSpan> Cache-Control aware Dynamic expiry calculation

Cache Key Generation

The default cache key generator creates keys using:

  • HTTP method (GET, POST, etc.)
  • Request URI
  • Authorization header (if present)

Example: GET:https://api.example.com/weather?city=London|auth:Bearer

Custom Cache Key Generator

public class CustomCacheKeyGenerator : ICacheKeyGenerator
{
    public string GenerateKey(HttpRequestMessage request)
    {
        var method = request.Method.Method;
        var uri = request.RequestUri?.ToString() ?? string.Empty;

        // Include user-specific headers
        var userId = request.Headers.GetValues("X-User-Id").FirstOrDefault();

        return $"{method}:{uri}:user:{userId}";
    }
}

Best Practices

1. Choose Appropriate Cache Duration

// Static data - longer cache
options.DefaultExpiry = TimeSpan.FromHours(1);

// Dynamic data - shorter cache
options.DefaultExpiry = TimeSpan.FromMinutes(5);

// Real-time data - very short cache
options.DefaultExpiry = TimeSpan.FromSeconds(30);

2. Consider Cache Size

// Limit memory usage
options.MaxCacheSize = 1_000; // Adjust based on available memory

3. Cache Invalidation Strategy

// Invalidate on data updates
public async Task UpdateUserAsync(User user)
{
    await _userRepository.UpdateAsync(user);

    // Remove from cache
    var request = new HttpRequestMessage(HttpMethod.Get, $"/api/users/{user.Id}");
    await _cachedClient.RemoveFromCacheAsync(request);
}

4. Handle Cache Failures Gracefully

options.ShouldCache = (request, response) =>
{
    try
    {
        return response.IsSuccessStatusCode &&
               response.Content.Headers.ContentLength < 1_000_000; // Don't cache large responses
    }
    catch
    {
        return false; // Skip caching on errors
    }
};

Integration with Reliable.HttpClient

Caching works seamlessly with resilience policies:

services.AddMemoryCache();  // Required
services.AddHttpClient<ApiClient>()
    .AddResilience(options =>  // Retry + Circuit Breaker
    {
        options.Retry.MaxRetries = 3;
        options.CircuitBreaker.FailuresBeforeOpen = 5;
    });

services.AddHttpClientCaching<ApiClient, ApiResponse>(options =>  // + Caching
{
    options.DefaultExpiry = TimeSpan.FromMinutes(5);
});

Execution Order: Cache Check → Resilience Policies → HTTP Request → Cache Store

Performance Considerations

  • Memory Usage: Monitor cache size, especially for large responses
  • Serialization: JSON serialization overhead for complex objects
  • Thread Safety: All cache providers are thread-safe
  • GC Pressure: Use appropriate expiry times to avoid memory leaks

License

This project is licensed under the MIT License - see the LICENSE file for details.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Reliable.HttpClient.Caching:

Package Downloads
KodySu.Client

Типобезопасный клиент для API kody.su (поиск информации по телефонным номерам).

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.2 359 8/29/2025
1.0.1 153 8/29/2025
1.0.0 157 8/29/2025
1.0.0-alpha1 173 8/29/2025

Initial alpha release of Reliable.HttpClient.Caching.
     Features: HTTP response caching with memory cache and custom cache providers.