DKNet

Map CRUD endpoints

Part of DKNet.SlimBus.Generators. {Entity}CrudEndpoints.g.cs is generated only when the compiling project references DKNet.AspCore.Extensions — a project that only wants requests/handlers (no ASP.NET Core dependency) gets exactly that, with no file full of unresolved types forced on it. When it is generated, it composes the existing DKNet.AspCore.Extensions mappers behind one call:

app.MapGroup("/products").MapProductCrud();
// By operation kind — no DELETE route is registered at all.
app.MapGroup("/products").MapProductCrud(o => o.Exclude(CrudOp.Delete));

// By route name — `ChangePrice` is withdrawn, `Rename` keeps the plain `{id}` PUT.
app.MapGroup("/products").MapProductCrud(o => o.Exclude("ChangePrice"));

Map{Entity}Crud validates every route name the entity has up front, then for each operation checks both its CrudOp and its route-name exclusion before mapping, and applies operation-kind settings before name settings.

Map{Entity}Crud(this RouteGroupBuilder, Action<CrudMapOptions>? configure = null) registers:

Operation Route Response
GET by id {id} 200 + DTO / 404
GET list (paged) / 200
POST create / 201 + DTO body (Location header is the placeholder /)
PUT — first [CrudUpdate] {id} 200 + DTO body / 404
PUT — additional [CrudUpdate]s {id}/{kebab-case-method-name} 200 + DTO body / 404
[CrudAction] (POST/PUT/PATCH) {id}/{segment} 200 + DTO body / 404
DELETE by id {id} 204 / 404, or 409 when the database rejects the delete

ValidateRouteNames is emitted with every route name the entity has and runs before anything is mapped, so a name Exclude/Configure passed that the entity does not have throws ArgumentException there. Each registration is then behind both guards — Exclude(CrudOp.Update) drops both PUTs, Exclude("Rename") drops only the second — and options.Apply is what runs a route’s settings, operation-kind first, name second. Naming a route whose operation is excluded is not an error: the name is still validated, and the setting is then silently dropped along with the route.

⚙️ Configuration reference

CrudMapOptions is declared in DKNet.AspCore.Extensions, which owns its full member reference: see Configure generated CRUD routes. This generator only decides which route each Exclude/Configure call reaches — by the names and segments in Name requests and routes.

🧱 Where it fits

Map{Entity}Crud composes MapGetById, MapGetList, MapDeleteById, MapPost, MapPutById, MapActionById and MapParameterlessActionById from DKNet.AspCore.Extensions — no new mapping layer. It never runs without that package referenced; see Generate CRUD requests for what exists without it.

⚠️ Gotchas & limits