Nefarius.HttpClient.LiteDbCache
2.5.0
Prefix Reserved
dotnet add package Nefarius.HttpClient.LiteDbCache --version 2.5.0
NuGet\Install-Package Nefarius.HttpClient.LiteDbCache -Version 2.5.0
<PackageReference Include="Nefarius.HttpClient.LiteDbCache" Version="2.5.0" />
<PackageVersion Include="Nefarius.HttpClient.LiteDbCache" Version="2.5.0" />
<PackageReference Include="Nefarius.HttpClient.LiteDbCache" />
paket add Nefarius.HttpClient.LiteDbCache --version 2.5.0
#r "nuget: Nefarius.HttpClient.LiteDbCache, 2.5.0"
#:package Nefarius.HttpClient.LiteDbCache@2.5.0
#addin nuget:?package=Nefarius.HttpClient.LiteDbCache&version=2.5.0
#tool nuget:?package=Nefarius.HttpClient.LiteDbCache&version=2.5.0
Nefarius.HttpClient.LiteDbCache
Adds disk-based response caching to HttpClient named instances using LiteDB.
Motivation
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. 😉
Features
- 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 or overridden per request.
- Upstream
Cache-Control/Expiresheaders can optionally bound or skip storage. - Expired entries can optionally be served when a refresh fails (stale-if-error / offline fallback).
How to use
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.
Honour upstream cache headers
Set HonorCacheControl to let the remote Cache-Control and Expires headers influence storage. This stays off by
default so existing clients keep their configured TTLs.
}).AddLiteDbCache(options =>
{
options.ConnectionString = @"C:\Temp\ifconfig.db";
options.CollectionName = "ifconfig-response-cache";
options.EntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10);
options.EntryOptions.HonorCacheControl = true;
});
When enabled:
Cache-Control: no-storeandno-cacheskip caching entirely (no-cacheis treated as a bypass, not as HTTP revalidation withETag/Last-Modified).max-age(minusAge/ apparent age fromDate) is an upper bound on how long the entry may be reused.Expiresis used only whenmax-ageis absent.- Responses that are already stale on arrival are not stored.
- Local expiration options still apply; the earliest expiry wins.
Per-request cache options
Attach a LiteDbCacheEntryOptions instance to override the named client's defaults for that call only. Convenience
overloads exist for GET, HEAD, DELETE, POST, PUT, and PATCH (the verbs the cache engine currently keys), including the
common System.Net.Http.Json
helpers:
LiteDbCacheEntryOptions cache = new()
{
HonorCacheControl = true,
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(2)
};
HttpResponseMessage result = await client.GetAsync("/", cache, ct);
IpResponse? ip = await client.GetFromJsonAsync<IpResponse>("/", cache, ct);
You can still attach options to an existing HttpRequestMessage when you need custom methods, headers, or completion
behavior:
HttpRequestMessage request = new(HttpMethod.Get, "/");
request.Headers.Accept.Add(new("application/json"));
HttpResponseMessage result = await client.SendAsync(request, cache, ct);
Serve stale content when refresh fails
By default an expired entry is discarded before the remote call. Set ServeStaleOnError to keep it and return that
snapshot when the refresh fails (transport error, timeout, or a non-success status). Successful refreshes replace the
entry as usual. Caller cancellation is not treated as a failure.
options.EntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10);
options.EntryOptions.ServeStaleOnError = true;
Stale fallbacks still report IsCached() and also IsStale(), and include the X-LiteDb-Cache-Stale header.
Advanced usage
Cache database access
Inject the ILiteDbCacheDatabaseInstances interface to get access to the LiteDatabase instances and other database
management methods (cache purge and alike).
Documentation
Sources & 3rd party credits
This library benefits from these awesome projects ❤ (appearance in no special order):
| Product | Versions 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. |
-
net6.0
- LiteDB (>= 5.0.21)
- Microsoft.AspNet.WebApi.Client (>= 6.0.0)
-
net8.0
- LiteDB (>= 5.0.21)
- Microsoft.AspNet.WebApi.Client (>= 6.0.0)
-
net9.0
- LiteDB (>= 5.0.21)
- Microsoft.AspNet.WebApi.Client (>= 6.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.5.0 | 37 | 9/11/2026 |
| 2.4.1 | 1,749 | 1/24/2025 |
| 2.4.0 | 241 | 1/22/2025 |
| 2.3.0 | 629 | 11/20/2024 |
| 2.3.0-pre001 | 148 | 11/20/2024 |
| 2.2.2 | 447 | 7/9/2024 |
| 2.2.1 | 266 | 6/12/2024 |
| 2.2.0 | 406 | 6/12/2024 |
| 2.1.4 | 224 | 6/7/2024 |
| 2.1.3 | 222 | 6/7/2024 |
| 2.1.2 | 533 | 3/5/2024 |
| 2.1.1 | 209 | 2/27/2024 |
| 2.1.0-pre | 198 | 2/24/2024 |
| 2.0.6 | 231 | 2/23/2024 |
| 2.0.5-pre | 180 | 2/23/2024 |
| 2.0.4-pre | 212 | 2/23/2024 |
| 1.9.0 | 234 | 2/22/2024 |
| 1.8.0 | 263 | 2/22/2024 |
| 1.7.1 | 220 | 2/21/2024 |