DKNet

DKNet.AspCore.Idempotency.RedisStore

Redis-backed reservations and TTL-based response retention for .NET developers using DKNet idempotency.

✨ Why use it?

🚀 Quick Start

Use a .NET 10 ASP.NET Core project.

dotnet new web -f net10.0 -n PackageDemo
cd PackageDemo
dotnet add package DKNet.AspCore.Idempotency.RedisStore

Replace Program.cs with the example, then run dotnet run.

Set ConnectionStrings__Redis to a reachable Redis connection string. The Redis server must support the atomic SET NX GET operation used by StackExchange.Redis.

using DKNet.AspCore.Idempotency;
using DKNet.AspCore.Idempotency.RedisStore;
var builder = WebApplication.CreateBuilder(args);
var connection = builder.Configuration.GetConnectionString("Redis")
    ?? throw new InvalidOperationException("Set ConnectionStrings__Redis.");
builder.Services.AddIdempotencyWithRedisStore(connection);
var app = builder.Build();
app.MapPost("/orders", () => Results.Ok(new { Accepted = true }))
    .RequiredIdempotentKey();
await app.RunAsync();

POST twice with X-Idempotency-Key: order-1. The first returns 200 and the retry 409. Instances sharing this Redis database and prefix share the ledger.

🏗️ Architecture

The host selects a singleton Redis key store that uses an IConnectionMultiplexer and IDatabase directly.

The app supplies reachable Redis infrastructure. Existing multiplexer and distributed-cache registrations are retained independently; the store uses the multiplexer directly. No relational base, context or migration service participates.

🔄 How it works

A protected request validates its key, reserves in Redis, invokes the endpoint and writes eligible completion data; duplicates stop before the handler.

The core filter decides 409 versus replay. Reservations expire separately from completed entries. Redis loss or eviction and handlers exceeding the reservation lifetime can permit another execution.

🧩 Features