Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/simoncropp/replicant

A wrapper for HttpClient that caches to disk. Cached files, over the max specified, are deleted based on the last access times.
https://github.com/simoncropp/replicant

cache httpcache httpclient

Last synced: 8 days ago
JSON representation

A wrapper for HttpClient that caches to disk. Cached files, over the max specified, are deleted based on the last access times.

Awesome Lists containing this project

README

        

# Replicant

[![Build status](https://ci.appveyor.com/api/projects/status/2t806jcx34s3r796/branch/main?svg=true)](https://ci.appveyor.com/project/SimonCropp/Replicant)
[![NuGet Status](https://img.shields.io/nuget/v/Replicant.svg)](https://www.nuget.org/packages/Replicant/)

A wrapper for HttpClient that caches to disk. Cached files, over the max specified, are deleted based on the last access times.

**See [Milestones](../../milestones?state=closed) for release notes.**

Headers/Responses respected in caching decisions:

* [Expires](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expires)
* [Cache-Control max-age](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#expiration)
* [Cache-Control no-store](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#cacheability)
* [Cache-Control no-cache](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#cacheability)
* [Last-Modified](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified)
* [ETag](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag)

## NuGet package

https://nuget.org/packages/Replicant/

## Usage

### Default instance

There is a default static instance:


```cs
var content = await HttpCache.Default.DownloadAsync("https://httpbin.org/status/200");
```
snippet source | anchor

This caches to `{Temp}/Replicant`.

### Construction

An instance of HttpCache should be long running.


```cs
var httpCache = new HttpCache(
cacheDirectory,
// omit for default new HttpClient()
new HttpClient
{
Timeout = TimeSpan.FromSeconds(30)
},
// omit for the default of 1000
maxEntries: 10000);

// Dispose when finished
await httpCache.DisposeAsync();
```
snippet source | anchor

### Dependency injection

Add HttpClient as a singleton when using dependency injection.


```cs
var services = new ServiceCollection();
services.AddSingleton(_ => new HttpCache(CachePath));

using var provider = services.BuildServiceProvider();
var httpCache = provider.GetRequiredService();
Assert.NotNull(httpCache);
```
snippet source | anchor

Using HttpClient with [HttpClientFactory](https://docs.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests).


```cs
ServiceCollection services = new();
services.AddHttpClient();
services.AddSingleton(
_ =>
{
var clientFactory = _.GetRequiredService();
return new HttpCache(CachePath, () => clientFactory.CreateClient());
});

using var provider = services.BuildServiceProvider();
var httpCache = provider.GetRequiredService();
Assert.NotNull(httpCache);
```
snippet source | anchor

### Get a string


```cs
var content = await httpCache.StringAsync("https://httpbin.org/json");
```
snippet source | anchor

```cs
var lines = new List();
await foreach (var line in httpCache.LinesAsync("https://httpbin.org/json"))
{
lines.Add(line);
}
```
snippet source | anchor

### Get bytes


```cs
var bytes = await httpCache.BytesAsync("https://httpbin.org/json");
```
snippet source | anchor

### Get a stream


```cs
using var stream = await httpCache.StreamAsync("https://httpbin.org/json");
```
snippet source | anchor

### Download to a file


```cs
await httpCache.ToFileAsync("https://httpbin.org/json", targetFile);
```
snippet source | anchor

### Download to a stream


```cs
await httpCache.ToStreamAsync("https://httpbin.org/json", targetStream);
```
snippet source | anchor

### Manually add an item to the cache


```cs
using var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent("the content")
};
await httpCache.AddItemAsync(uri, response);
```
snippet source | anchor

### Use stale item on error

If an error occurs when re-validating a potentially stale item, then the cached item can be used as a fallback.


```cs
var content = httpCache.StringAsync(uri, staleIfError: true);
```
snippet source | anchor

### Customizing HttpRequestMessage

The HttpRequestMessage used can be customized using a callback.


```cs
var content = await httpCache.StringAsync(
uri,
modifyRequest: message =>
{
message.Headers.Add("Key1", "Value1");
message.Headers.Add("Key2", "Value2");
});
```
snippet source | anchor

### Full HttpResponseMessage

An instance of the HttpResponseMessage can be created from a cached item:


```cs
using var response = await httpCache.ResponseAsync("https://httpbin.org/status/200");
```
snippet source | anchor

## Influences / Alternatives

* [Tavis.HttpCache](https://github.com/tavis-software/Tavis.HttpCache)
* [CacheCow](https://github.com/aliostad/CacheCow)
* [Monkey Cache](https://github.com/jamesmontemagno/monkey-cache)

## Icon

[Cyborg](https://thenounproject.com/term/cyborg/689871/) designed by [Symbolon](https://thenounproject.com/symbolon/) from [The Noun Project](https://thenounproject.com).