Adds disk-based response caching to HttpClient named instances using LiteDB.
Sometimes a response from a remote HTTP service doesn't change frequently and fetching it again multiple times within a
certain time span is wasteful and puts unnecessary delays on the caller. Offline caching to the rescue! However,
manually storing and fetching responses gets verbose and complex fast, why not hide that complexity away and
let IHttpClientFactory deal with it behind the scenes?
This library provides the extension method AddLiteDbCache you can chain your named HTTP client call with and specify
an embedded database location to use for offline caching, no other code changes are required.
Why not use IMemoryCache?
The goal of the cache is to survive application/service restarts.
Why not use IDistributedCache?
This library is aimed at end-user clients where you wish to drag in as little dependency on 3rd party services as possible. An embedded database sitting in some folder does the trick there perfectly. It's usually not the brightest idea to require spinning up a Redis or MongoDB instance on a client's machine just to get some basic persisted storage capabilities. 😉
- Each named HTTP client gets its own backing cache database instance which is kept exclusively open by default throughout application lifetime for performance benefits.
- Cached entries expiration (and exclusion) can be configured globally per named instance.
- Per-request cache entry expiration options
(like
MemoryCacheEntryOptionsand similar) are technically possible; however due to how theHttpClientclass is structured would require writing a ton of wrapper methods that supply these options to eachHttpRequestMessage(which can not be conveniently overwritten); a task I am currently not fond of since it's a low priority anyway.- A great task for Source Generators!
- The upstream
Cache-Controlheader is currently completely ignored; it could be taken into consideration, if the user configured it to be honored. - Add some unit tests... maybe. Someday. 😅
Register one or
more named HTTP clients
with AddLiteDbCache. This example snippet registers a cached client that will query your public IP address
using https://ifconfig.me/ and cache the response for 10 minutes to a local embedded database
instance:
builder.Services.AddHttpClient("ifconfig", cfg =>
{
cfg.BaseAddress = new Uri("https://ifconfig.me");
}).AddLiteDbCache(options =>
{
// note: ensure that the path given already exists or you'll get a runtime exception
options.ConnectionString = @"C:\Temp\ifconfig.db";
options.CollectionName = "ifconfig-response-cache";
options.EntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10);
});This cached named client can now be consumed like any other HttpClient wherever needed:
HttpClient client = _clientFactory.CreateClient("ifconfig");
HttpResponseMessage result = await client.GetAsync("/", ct);
string? publicIP = await result.Content.ReadAsStringAsync(ct);If a cached entry exists, the response (headers, body content etc.) will be pulled and returned from the local database and no remote web request will be issued until the cache entry expires.
Inject the ILiteDbCacheDatabaseInstances interface to get access to the LiteDatabase instances and other database
management methods (cache purge and alike).
This library benefits from these awesome projects ❤ (appearance in no special order):
