DKNet

DKNet.AspCore.Idempotency.NpgsqlStore

A PostgreSQL ledger for .NET developers using DKNet minimal-API 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.NpgsqlStore

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

Set ConnectionStrings__Idempotency to a reachable PostgreSQL database connection string. The account must be able to apply the packaged migrations.

using DKNet.AspCore.Idempotency;
using DKNet.AspCore.Idempotency.NpgsqlStore;
var builder = WebApplication.CreateBuilder(args);
var connection = builder.Configuration.GetConnectionString("Idempotency")
    ?? throw new InvalidOperationException("Set ConnectionStrings__Idempotency.");
builder.Services.AddIdempotencyWithNpgsqlStore(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. The ledger is shared by hosts using this database.

🏗️ Architecture

The host selects the PostgreSQL store, whose context factory serves ledger operations and startup migrations.

The provider registers a singleton store and factory, with fresh contexts per operation. The database is supplied by the application operator; startup applies this provider’s migrations.

🔄 How it works

The host registers the SQL provider, applies pending migrations, then validates and reserves each protected request before running and retaining its result.

A live collision is a duplicate; an expired collision can be reclaimed by a conditional update. The core filter decides whether a result is cacheable. Expired rows are not automatically purged.

🧩 Features