agentskills.codes
AS

aspnet-minimal-apis

Structure, organize, and extend ASP.NET Core Minimal APIs using route groups, parameter binding, endpoint metadata, and filters — without controllers. Covers MapGroup with RouteGroupBuilder extension methods, all binding sources ([FromBody], [FromServices], [FromRoute], [AsParameters]), endpoint con

Install

mkdir -p .claude/skills/aspnet-minimal-apis && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/16625" && unzip -o skill.zip -d .claude/skills/aspnet-minimal-apis && rm skill.zip

Installs to .claude/skills/aspnet-minimal-apis

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Structure, organize, and extend ASP.NET Core Minimal APIs using route groups, parameter binding, endpoint metadata, and filters — without controllers. Covers MapGroup with RouteGroupBuilder extension methods, all binding sources ([FromBody], [FromServices], [FromRoute], [AsParameters]), endpoint conventions (WithName, WithSummary, WithTags, RequireAuthorization, ExcludeFromDescription), endpoint filters, and the static-class/named-method organization pattern. Trigger whenever the user writes, reviews, or asks about Minimal API routing, route groups, parameter binding, endpoint registration, MapGet/MapPost/MapPut/MapDelete, IEndpointRouteBuilder, RouteGroupBuilder, [AsParameters], DI in handlers, or organizing Minimal API endpoints — even if they don't mention these terms by name. Always prefer this skill over guessing; the binding and group APIs have subtle rules that are easy to get wrong.
903 charsno explicit “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)

About this skill

ASP.NET Core Minimal APIs Skill

Minimal APIs let you define HTTP endpoints directly in C# without controllers, using a functional style that's concise, composable, and easy to test. The key to keeping them maintainable at scale is to apply a consistent organization pattern from the start.

Why this matters

The default inline-lambda style works for small APIs but quickly becomes unwieldy. Route groups, named handler methods, and RouteGroupBuilder extension methods give you the structure of controllers without the ceremony — and they're the prerequisite for TypedResults to work properly (see aspnet-typed-results for response types) and for OpenAPI to self-document (see aspnet-openapi).

Quick reference

TopicSee
Route groups, MapGroup, RouteGroupBuilder extension methods, nestingroute-groups.md
Binding: route, query, body, DI, headers, [AsParameters], special typesparameter-binding.md
WithName, WithSummary, WithTags, RequireAuthorization, ExcludeFromDescription, Acceptsendpoint-metadata.md
IEndpointFilter, filter factories, filter orderingfilters.md
Common mistakespitfalls.md

The standard organization pattern

Define a static class per feature area. Expose a single extension method on RouteGroupBuilder that registers all routes. Keep handler methods as private static or internal static named methods below the registration method.

public static class ProductEndpoints
{
    // Called from Program.cs or a central mapping extension
    public static RouteGroupBuilder MapProductEndpoints(this RouteGroupBuilder group)
    {
        _ = group.MapGet("/", GetProducts)
            .WithName("GetProducts")
            .WithSummary("List all products");

        _ = group.MapGet("/{id:guid}", GetProduct)
            .WithName("GetProduct")
            .WithSummary("Get a product by ID");

        _ = group.MapPost("/", CreateProduct)
            .WithName("CreateProduct")
            .WithSummary("Create a new product")
            .RequireAuthorization();

        return group;
    }

    // Handler methods: named, static, directly callable in unit tests
    static async Task<Ok<ProductDto[]>> GetProducts(
        [FromServices] IDocumentSession session,
        CancellationToken cancellationToken) =>
        TypedResults.Ok(await session.Query<ProductDto>().ToArrayAsync(cancellationToken));

    static async Task<Results<Ok<ProductDto>, NotFound>> GetProduct(
        Guid id,
        [FromServices] IDocumentSession session,
        CancellationToken cancellationToken)
    {
        var product = await session.LoadAsync<ProductDto>(id, cancellationToken);
        return product is null ? TypedResults.NotFound() : TypedResults.Ok(product);
    }

    static async Task<Created<ProductDto>> CreateProduct(
        [FromBody] CreateProductRequest request,
        [FromServices] IMessageBus bus,
        CancellationToken cancellationToken)
    {
        var product = await bus.InvokeAsync<ProductDto>(new CreateProductCommand(request), cancellationToken);
        return TypedResults.Created($"/api/products/{product.Id}", product);
    }
}

Register centrally in Program.cs:

app.MapGroup("/api/products")
   .WithTags("Products")
   .MapProductEndpoints();

Essential rules at a glance

  • Extract handler methods — inline lambdas can't return Results<T1,T2> and can't be unit-tested directly.
  • Group at the call site — prefix, tags, auth, and API versioning belong on the outer group, not inside the endpoint class.
  • [FromServices] for DI — service parameters are not injected automatically unless marked; use [FromServices] (or FromKeyedServices) to be explicit.
  • [AsParameters] — wraps multiple query/route/header params into a single record for clean large parameter lists.
  • Route constraints{id:guid}, {page:int:min(1)} prevent bad input from reaching the handler.
  • CancellationToken — always accept it in async handlers; it's bound automatically from the request without any attribute.

What to read next

aspnet-sse

aalmada

Implement Server-Sent Events (SSE) in ASP.NET Core using TypedResults.ServerSentEvents, SseItem<T>, and Channel-based pub/sub — including the notification service pattern, multi-instance Redis scaling, and the SseParser client. Trigger whenever the user writes, reviews, or asks about SSE, real-time

00

etag

aalmada

Use this skill for any request involving HTTP ETags, conditional requests, or optimistic concurrency in REST APIs: implementing/explaining ETag headers, preventing lost updates, designing cache validation or conditional GET/PUT/DELETE, explaining If-Match, If-None-Match, 304 Not Modified, or 412 Pre

00

tunit

aalmada

Use this skill to write, review, and fix TUnit tests in .NET projects: for new test classes, assertions, data-driven tests, lifecycle hooks, debugging, migrating from xUnit/NUnit, choosing assertions, using Bogus, NSubstitute mocks, integration tests, or questions about parallelism and test ordering

00

bogus

aalmada

Generate realistic fake data for .NET projects using the Bogus library. Use for test data, database seeding, randomized object creation, and prototyping. Always prefer Bogus over hand-rolled random data or hardcoded test values. Trigger for any .NET test, data seeding, or sample data scenario. Use t

00

bunit

aalmada

Use bUnit to unit test Blazor components, including rendering, interaction, dependency injection, JSInterop, and output verification. Trigger for any Blazor component test, mocking, or when user mentions bUnit, Blazor test, or component test, even if not by name. Prefer this skill over hand-rolled t

00

refit

aalmada

Use Refit to define type-safe REST clients in .NET as C# interfaces backed by HttpClient — covering interface definition (HTTP verb attributes, parameter binding, return types), DI registration with AddRefitClient, DelegatingHandler pipelines for auth/headers/logging, error handling with IApiRespons

00

Search skills

Search the agent skills registry