/Carter.Cache

A caching middleware for your Carter API

Primary LanguageC#MIT LicenseMIT

Carter.Cache Mit License

An extensible library to cache your Carter modules.

Builds

Github Branch Coverage
.NET master CodeCov

Packages

Package NuGet (Stable) MyGet (Prerelease)
Carter.Cache NuGet MyGet
Carter.Cache.Memcached NuGet MyGet
Carter.Cache.Redis NuGet MyGet

Installation

Install via nuget

PM> Install-Package Carter.Cache

This library depends on Carter to properly work, you can install Carter using the following command:

PM> Install-Package Carter

Sample usage

  1. Add carter caching to your Program.cs:
var builder = WebApplication.CreateBuilder(args);

//The rest of your Program.cs configuration ....

//It is recommended to always provide a caching max size limit
builder.Services.AddCarterCaching(new CachingOption(2048));
builder.Services.AddCarter();
  1. Define a Configuration usage
var app = builder.Build();

//The rest of your configuration usage ....

app.UseCarterCaching();
app.MapCarter();

app.Run();
  1. Add the Cacheable clause to your module:
    public class HomeModule : ICarterModule
    {
        public void AddRoutes(IEndpointRouteBuilder app)
        {
            app.MapGet("/", (HttpContext ctx) =>
            {
                ctx.AsCacheable(10); //In Seconds

                ctx.Response.StatusCode = 200;
                return ctx.Response.WriteAsync("Hello world");
            });
        }
    }

The default configuration does use the Microsoft.Extensions.Caching.Memory library as a default caching mechanism. Note: By default memory caching can put lots of pressure on the memory of your system, please refer to the following microsoft in-memory cache docs for basics on usage.

Customization

You can easily define a custom Store by implementing the ICacheStore interface with the following signature:

    public interface ICacheStore
    {
        bool TryGetValue(string key, out CachedResponse cachedResponse);

        void Set(string key, CachedResponse response, TimeSpan expiration);

        void Remove(string key);
    }

Also a custom Key can be easily defined by implementing the ICacheKey interface:

    public interface ICacheKey
    {
        string Get(HttpRequest request);
    }

Redis store

A redis store which includes the dependency on StackExchange.Redis and can be used as a replacement of the memory store.

Firstly, install the library using .net cli dotnet add package Carter.Cache.Redis or using Package Manager Install-Package Carter.Cache.Redis. The usage requires the following configurations on the Startup.cs file:

//The rest of your Program.cs ....

builder.Services.AddSingleton<ICacheStore>(new RedisStore("127.0.0.1:6379"));
builder.Services.AddSingleton(provider => new CachingOption()
{
    Store = provider.GetRequiredService<ICacheStore>()
});

IServiceProvider serviceProvider = builder.Services.BuildServiceProvider();

builder.Services.AddCarterCaching(serviceProvider.GetRequiredService<CachingOption>());
builder.Services.AddCarter();

As part of the redis definition, you can optionally provide a json serializer definition to be used for the serialization of the cached response. This uses the System.Text.Json library.

//The rest of your Program.cs ....

var jsonOptions = new System.Text.Json.JsonSerializerOptions() { AllowTrailingCommas = true };

builder.Services.AddSingleton<ICacheStore>(new RedisStore("127.0.0.1:6379", jsonOptions));
builder.Services.AddSingleton(provider => new CachingOption()
{
    Store = provider.GetRequiredService<ICacheStore>()
});

IServiceProvider serviceProvider = builder.Services.BuildServiceProvider();

builder.Services.AddCarterCaching(serviceProvider.GetRequiredService<CachingOption>());
builder.Services.AddCarter();

Memcached store

Alternatively, a memcached store can also be included as an alternatively, using a dependency on the library EnyimMemcachedCore.

To install, using .net cli dotnet add package Carter.Cache.Memcached or using Package Manager Install-Package Carter.Cache.Memcached. The usage requires the following reconfigurations on the ConfigureServices method of Startup:

//The rest of your Program.cs ....

//Point to the server / port desired
builder.Services.AddEnyimMemcached(options => options.AddServer("127.0.0.1", 11211));

//Resolve the IMemcachedClient dependency using EnyimMemcached
builder.Services.AddSingleton<ICacheStore>(provider => new MemcachedStore(provider.GetRequiredService<IMemcachedClient>()));

//Define Caching options using the store configured
builder.Services.AddSingleton(provider => new CachingOption()
{
    Store = provider.GetRequiredService<ICacheStore>()
});

IServiceProvider serviceProvider = services.BuildServiceProvider();

//Pass it as a dependency to the add
services.AddCarterCaching(serviceProvider.GetRequiredService<CachingOption>());

For more information check the samples included.