api-versioning
API versioning strategies for ASP.NET Core. Covers Asp.Versioning library, URL segment,…
.NET 10 minimal APIs — the default for building HTTP endpoints. Covers MapGroup, endpoint filters, TypedResults, OpenAPI metadata, parameter binding, and route conventions. Load this skill when creating API endpoints, configuring routing, setting up OpenAPI documentation, or
$ npx -y skills add codewithmukesh/dotnet-claude-kit --skill minimal-api --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/minimal-apiContext preview
The summary Claude sees to decide when to auto-load this skill.
.NET 10 minimal APIs — the default for building HTTP endpoints. Covers MapGroup, endpoint filters, TypedResults, OpenAPI metadata, parameter binding, and route conventions. Load this skill when creating API endpoints, configuring routing, setting up OpenAPI documentation, or
name: minimal-api description: > .NET 10 minimal APIs — the default for building HTTP endpoints. Covers MapGroup, endpoint filters, TypedResults, OpenAPI metadata, parameter binding, and route conventions. Load this skill when creating API endpoints, configuring routing, setting up OpenAPI documentation, or when the user mentions "endpoint", "MapGet", "MapPost", "MapGroup", "TypedResults", "route", "minimal API", "OpenAPI", "swagger", "rate limiting", or "output caching".
1. **Minimal APIs are the default** — Use controllers only when migrating legacy code. Minimal APIs are lighter, faster, and compose well with any architecture style. 2. **Group endpoints with `MapGroup`** — Never scatter individual `MapGet`/`MapPost` calls in `Program.cs`. Group related endpoints together. 3. **Use `TypedResults` for OpenAPI** — `TypedResults.Ok(value)` gives you compile-time type safety AND correct OpenAPI documentation. `Results.Ok(value)` does not. 4. **Metadata over comments** — Use `.WithName()`, `.WithTags()`, `.WithSummary()` to document endpoints. The metadata feeds into OpenAPI specs.
Every endpoint group lives in its own file and implements `IEndpointGroup`. A single `app.MapEndpoints()` call in `Program.cs` discovers and registers all groups automatically. **Program.cs never changes when you add new endpoint groups.**
// Extensions/IEndpointGroup.cs
public interface IEndpointGroup
{
void Map(IEndpointRouteBuilder app);
}// Extensions/EndpointExtensions.cs
public static class EndpointExtensions
{
public static WebApplication MapEndpoints(this WebApplication app)
{
var groups = typeof(Program).Assembly
.GetTypes()
.Where(t => t.IsAssignableTo(typeof(IEndpointGroup)) && !t.IsInterface && !t.IsAbstract)
.Select(Activator.CreateInstance)
.Cast<IEndpointGroup>();
foreach (var group in groups)
group.Map(app);
return app;
}
}// Program.cs — this NEVER changes when adding endpoints var app = builder.Build(); app.MapEndpoints(); app.Run();
// Features/Orders/OrderEndpoints.cs — one file per endpoint group
public sealed class OrderEndpoints : IEndpointGroup
{
public void Map(IEndpointRouteBuilder app)
{
var group = app.MapGroup("/api/orders").WithTags("Orders");
group.MapPost("/", CreateOrder)
.WithName("CreateOrder")
.WithSummary("Create a new order")
.Produces<OrderResponse>(StatusCodes.Status201Created)
.ProducesValidationProblem()
.RequireAuthorization();
group.MapGet("/{id:guid}", GetOrder)
.WithName("GetOrder")
.Produces<OrderResponse>()
.ProducesProblem(StatusCodes.Status404NotFound);
group.MapGet("/", ListOrders)
.WithName("ListOrders")
.Produces<PagedList<OrderResponse>>();
}
private static async Task<Results<Created<OrderResponse>, ValidationProblem>> CreateOrder(
CreateOrderRequest request,
ISender sender,
CancellationToken ct)
{
var result = await sender.Send(new CreateOrder.Command(request.CustomerId, request.Items), ct);
return result.IsSuccess
? TypedResults.Created($"/api/orders/{result.Value.Id}", result.Value)
: TypedResults.ValidationProblem(result.Errors);
}
private static async Task<Results<Ok<OrderResponse>, NotFound>> GetOrder(
Guid id,
ISender sender,
CancellationToken ct)
{
var result = await sender.Send(new GetOrder.Query(id), ct);
return result.IsSuccess
? TypedResults.Ok(result.Value)
: TypedResults.NotFound();
}
private static async Task<Ok<PagedList<OrderResponse>>> ListOrders(
[AsParameters] ListOrdersQuery query,
ISender sender,
CancellationToken ct)
{
var result = await sender.Send(query, ct);
return TypedResults.Ok(result);
}
}`TypedResults` provides compile-time guarantees and automatic OpenAPI schema generation.
// GOOD — TypedResults with union return type
private static async Task<Results<Ok<Product>, NotFound, ValidationProblem>> GetProduct(
Guid id,
AppDbContext db,
CancellationToken ct)
{
var product = await db.Products.FindAsync([id], ct);
return product is not null
? TypedResults.Ok(product)
: TypedResults.NotFound();
}.NET 10 minimal APIs bind parameters from route, query, header, body, and DI automatically.
// Route parameters
app.MapGet("/orders/{id:guid}", (Guid id) => ...);
// Query parameters (nullable = optional)
app.MapGet("/orders", (int page, int? pageSize, string? status) => ...);
// Complex query parameters with [AsParameters]
public record ListOrdersQuery(int Page = 1, int PageSize = 20, string? Status = null);
app.MapGet("/orders", ([AsParameters] ListOrdersQuery query) => ...);
// Header binding
app.MapGet("/orders", ([FromHeader(Name = "X-Correlation-Id")] string? correlationId) => ...);
// DI services are auto-resolved (no attribute needed)
app.MapPost("/orders", (CreateOrderRequest request, ISender sender) => ...);Filters are the minimal API equivalent of action filters. Use them for cross-cutting concerns like validation, logging, and idempotency checks.
The canonical `ValidationFilter<TRequest>` implementation (FluentValidation, resolves the validator from DI and skips gracefully when none is registered) lives in the **error-handling** skill — use that one, don't re-implement it per project.
// Apply the canonical filter (see error-handling skill) to a mutating endpoint
group.MapPost("/", CreateOrder)
.API versioning strategies for ASP.NET Core. Covers Asp.Versioning library, URL segment,…
Architecture conformance check: verifies an existing codebase against its declared…
Architecture selection advisor for .NET applications. Asks structured questions about domain…
.NET Aspire for cloud-native orchestration. Covers AppHost configuration, service defaults,…
Authentication and authorization for ASP.NET Core. Covers JWT bearer tokens, OpenID Connect,…
Autonomous iteration loops for .NET: drive a broken build or failing test suite to green with…