DKNet

Persist reservations and responses in PostgreSQL

Part of DKNet.AspCore.Idempotency.NpgsqlStore. Protect an endpoint after registering this provider:

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()).RequiredIdempotentKey();
await app.RunAsync();

The PostgreSQL provider uses the shared insert-or-reclaim protocol and replaces the reservation with response data.

The provider supplies the concrete context, migrations, body column type text, and structured unique-violation classification: PostgresException SQL state 23505. The shared reservation protocol owns insert, duplicate lookup, expired-row reclaim, and completion. The shared schema reference owns the field and index definitions.

Migrations run during host startup through IdempotencyMigrationHostedService<TContext>. A defensive per-connection guard also checks pending migrations on first store use. The migrations history table is migrate.IdempotencyDbContext; the ledger table is IdempotencyKeys.

⚙️ Configuration reference

Provider setting Value Effect
Design-time environment variable IDEMPOTENCY_NPGSQL_CONNECTION Required by the internal EF design-time factory.
Migrations assembly This provider assembly Keeps migrations with the provider.
Migrations history migrate.IdempotencyDbContext Records applied provider migrations.
Retry policy 3 retries, maximum 5-second delay PostgreSQL transient retry configuration.
Query splitting SplitQuery PostgreSQL EF query option.

🧱 Where it fits

The package overview shows the host registrations and dependencies behind this capability. The core filter and selected store have separate responsibilities.

The consumer host selects this package’s components and supplies the runtime dependencies shown in the package architecture.

⚠️ Gotchas & limits