Openapi

codewithmukesh/dotnet-claude-kit/skills/openapi

by codewithmukesh23300897f4d1No license754 starsListed Oct 8, 2026Updated Oct 8, 2026Repository updated 2 months ago

Built-in OpenAPI support for .NET 10 applications. Covers document generation, transformers, TypedResults metadata, security schemes, XML comments, build-time generation, and multiple document support. No Swashbuckle needed. Load this skill when setting up API documentation, customizing OpenAPI output, adding security schemes to docs, or when the user mentions "OpenAPI", "AddOpenApi", "MapOpenApi", "document transformer", "operation transformer", "schema transformer", "OpenAPI 3.1", "API documentation", "Swashbuckle replacement", "Produces", "WithSummary", "WithDescription", "ProblemDetails", "Kiota", or "client generation".

Instructions only

OpenAPI

Core Principles

  1. Built-in, not Swashbuckle — .NET 10 ships Microsoft.AspNetCore.OpenApi as the official, framework-maintained OpenAPI solution. Swashbuckle was removed from templates in .NET 9 and is no longer recommended.
  2. TypedResults drive the schema — TypedResults.Ok<T>() automatically generates correct OpenAPI response schemas. Results.Ok() does not. Always use TypedResults.
  3. Transformers over workarounds — Document, operation, and schema transformers compose cleanly. Use them for security schemes, global responses, and schema customization.
  4. Metadata on every endpoint — Use .WithName(), .WithSummary(), .WithTags() on every endpoint. This metadata feeds directly into the OpenAPI spec and client generators.

Patterns

Basic Setup

csharp
var builder = WebApplication.CreateBuilder(args);builder.Services.AddOpenApi();
var app = builder.Build();
if (app.Environment.IsDevelopment()){    app.MapOpenApi();  // Serves at /openapi/v1.json}

Endpoint Metadata

csharp
group.MapPost("/", CreateOrder)    .WithName("CreateOrder")    .WithSummary("Create a new order")    .WithDescription("Creates a new order for the specified customer.")    .Produces<OrderResponse>(StatusCodes.Status201Created)    .ProducesValidationProblem()    .ProducesProblem(StatusCodes.Status500InternalServerError);

With TypedResults, response metadata is inferred automatically:

csharp
static async Task<Results<Created<OrderResponse>, ValidationProblem>> CreateOrder(    CreateOrderRequest request, ISender sender, CancellationToken ct){    var result = await sender.Send(new CreateOrder.Command(request), ct);    return result.IsSuccess        ? TypedResults.Created($"/api/orders/{result.Value.Id}", result.Value)        : TypedResults.ValidationProblem(result.Errors);}

Bearer Token Security Scheme

csharp
builder.Services.AddOpenApi(options =>{    options.AddDocumentTransformer<BearerSecuritySchemeTransformer>();});
internal sealed class BearerSecuritySchemeTransformer(    IAuthenticationSchemeProvider authSchemeProvider) : IOpenApiDocumentTransformer{    public async Task TransformAsync(OpenApiDocument document,        OpenApiDocumentTransformerContext context, CancellationToken ct)    {        var schemes = await authSchemeProvider.GetAllSchemesAsync();        if (!schemes.Any(s => s.Name == "Bearer"))            return;
        document.Components ??= new OpenApiComponents();        document.Components.SecuritySchemes = new Dictionary<string, IOpenApiSecurityScheme>        {            ["Bearer"] = new OpenApiSecurityScheme            {                Type = SecuritySchemeType.Http,                Scheme = "bearer",                BearerFormat = "JWT",                In = ParameterLocation.Header            }        };
        foreach (var operation in document.Paths.Values.SelectMany(p => p.Operations))        {            operation.Value.Security ??= [];            operation.Value.Security.Add(new OpenApiSecurityRequirement            {                [new OpenApiSecuritySchemeReference("Bearer", document)] = []            });        }    }}

Document Info Transformer

csharp
builder.Services.AddOpenApi(options =>{    options.AddDocumentTransformer((document, context, ct) =>    {        document.Info = new()        {            Title = "Checkout API",            Version = "v1",            Description = "API for processing orders and payments."        };        return Task.CompletedTask;    });});

Multiple OpenAPI Documents

csharp
builder.Services.AddOpenApi("v1");builder.Services.AddOpenApi("internal", options =>{    options.AddDocumentTransformer<BearerSecuritySchemeTransformer>();});
// Endpoints choose their document via WithGroupNameapp.MapGet("/public", () => "Hello").WithGroupName("v1");app.MapGet("/admin", () => "Secret").WithGroupName("internal");

Endpoints without .WithGroupName() appear in all documents.

XML Documentation Comments (.NET 10)

Enable in the project file — the source generator extracts <summary>, <param>, <response> tags automatically:

xml
<PropertyGroup>    <GenerateDocumentationFile>true</GenerateDocumentationFile></PropertyGroup>
csharp
/// <summary>Retrieves a project board by ID.</summary>/// <param name="id">The project board ID.</param>/// <response code="200">Returns the project board.</response>/// <response code="404">Board not found.</response>static async Task<Results<Ok<Board>, NotFound>> GetBoard(int id, AppDbContext db){    var board = await db.Boards.FindAsync(id);    return board is not null ? TypedResults.Ok(board) : TypedResults.NotFound();}

XML comments on lambdas are not captured by the compiler. Use named methods.

Schema Transformer

csharp
options.AddSchemaTransformer((schema, context, ct) =>{    if (context.JsonTypeInfo.Type == typeof(decimal))    {        schema.Format = "decimal";    }    return Task.CompletedTask;});

Per-Endpoint Operation Transformer (.NET 10)

csharp
app.MapGet("/old", () => "deprecated")    .AddOpenApiOperationTransformer((operation, context, ct) =>    {        operation.Deprecated = true;        return Task.CompletedTask;    });

Build-Time Document Generation

xml
<PackageReference Include="Microsoft.Extensions.ApiDescription.Server" Version="*" /><PropertyGroup>    <OpenApiDocumentsDirectory>.</OpenApiDocumentsDirectory></PropertyGroup>

The spec file is generated in the output directory during build.

YAML Endpoint (.NET 10)

csharp
app.MapOpenApi("/openapi/{documentName}.yaml");

Anti-patterns

Don't Use Swashbuckle for New Projects

csharp
// BAD — removed from .NET 9+ templates, maintenance concernsbuilder.Services.AddSwaggerGen();app.UseSwagger();app.UseSwaggerUI();
// GOOD — built-in OpenAPIbuilder.Services.AddOpenApi();app.MapOpenApi();

Don't Use WithOpenApi() in .NET 10

csharp
// BAD — deprecated, produces ASPDEPR002 warningapp.MapGet("/", () => "hello").WithOpenApi(op => { op.Deprecated = true; return op; });
// GOOD — use per-endpoint operation transformerapp.MapGet("/", () => "hello")    .AddOpenApiOperationTransformer((op, ctx, ct) =>    {        op.Deprecated = true;        return Task.CompletedTask;    });

Don't Use Untyped Results

csharp
// BAD — Results.Ok doesn't contribute to OpenAPI schemastatic async Task<IResult> GetOrder(Guid id, AppDbContext db){    var order = await db.Orders.FindAsync(id);    return order is not null ? Results.Ok(order) : Results.NotFound();}
// GOOD — TypedResults with union return typestatic async Task<Results<Ok<Order>, NotFound>> GetOrder(Guid id, AppDbContext db){    var order = await db.Orders.FindAsync(id);    return order is not null ? TypedResults.Ok(order) : TypedResults.NotFound();}

Don't Skip WithName on Endpoints

csharp
// BAD — client generators produce poor method names without operationIdgroup.MapGet("/{id:guid}", GetOrder);
// GOOD — operationId feeds into generated client method namesgroup.MapGet("/{id:guid}", GetOrder).WithName("GetOrder");

Don't Use OpenApiAny in .NET 10

csharp
// BAD — OpenApiAny types removed in Microsoft.OpenApi v2.xschema.Example = new OpenApiString("2025-01-01");
// GOOD — use JsonNode from System.Text.Json.Nodesschema.Example = JsonValue.Create("2025-01-01");

Decision Guide

ScenarioRecommendation
New API projectAddOpenApi() + MapOpenApi() (built-in)
API documentation UIScalar (MapScalarApiReference())
Security schemes in docsDocument transformer with IOpenApiDocumentTransformer
Response documentationTypedResults with union return types
XML doc integration<GenerateDocumentationFile>true</GenerateDocumentationFile>
Multiple API versionsMultiple AddOpenApi("v1") calls + WithGroupName()
Client code generationKiota (Microsoft recommended) or NSwag
Build-time specMicrosoft.Extensions.ApiDescription.Server package
OpenAPI version3.1 (default in .NET 10), force 3.0 if consumers require it
Per-endpoint customization.AddOpenApiOperationTransformer() on the endpoint

Source and attribution

Source:codewithmukesh/dotnet-claude-kitinskills/openapiat commit2330089

License: No license

Content belongs to its original authors. SourceWeft indexes it from a public repository.

Report or request removal

More from codewithmukesh/dotnet-claude-kit

Wrap Up

codewithmukesh

Captures end-of-session work, pending tasks and learnings into a handoff file, and reloads it at session start.

Productivity & Workflow754updated 2 months ago

Workflow Mastery

codewithmukesh

Claude Code workflow mastery for .NET developers. Covers parallel execution with git worktrees, plan mode strategy, verification loops, auto-formatting hooks, permission setup for dotnet CLI, prompting techniques, subagent patterns, and context discipline — token budget management, MCP-first navigation, lazy loading, and subagent isolation — all adapted for the .NET ecosystem. Load this skill when setting up Claude Code for a .NET project, optimizing workflows, running parallel sessions, when context is running low or sessions feel sluggish, when exploring a large codebase efficiently, or when the user mentions "productivity", "workflow", "parallel", "worktree", "plan mode", "permissions", "hooks", "10x", "setup Claude Code", "speed up development", "context", "tokens", "budget", "running out of context", "too many files", or "large codebase". Inspired by tips from Boris Cherny (creator of Claude Code) and the Anthropic team.

Awaiting classification754updated 2 months ago

Vertical Slice

codewithmukesh

Guides .NET developers in structuring applications with Vertical Slice Architecture, covering feature folders, endpoint grouping and handler patterns.

Software Development754updated 2 months ago

Testing

codewithmukesh

Testing strategy for .NET 10 applications. Covers xUnit v3, WebApplicationFactory for integration tests, Testcontainers for real database testing, Verify for snapshot testing, and the AAA pattern. Load this skill when writing tests, setting up test infrastructure, reviewing test coverage, or when the user mentions "test", "xUnit", "WebApplicationFactory", "Testcontainers", "integration test", "unit test", "bUnit", "snapshot test", "Verify", "test coverage", "AAA pattern", "WireMock", or "FakeTimeProvider".

Awaiting classification754updated 2 months ago

Tdd

codewithmukesh

Guided test-driven development workflow for .NET 10 using xUnit v3, WebApplicationFactory, Testcontainers, and Verify snapshots. Follows the strict red-green-refactor cycle. Use when: "TDD", "test-driven", "let's TDD this", "red green refactor", "write the test first", or when building a feature with clear acceptance criteria.

Awaiting classification754updated 2 months ago

Spec

codewithmukesh

Turns a vague feature idea into an agreed, persisted specification file through structured questioning rounds.

Productivity & Workflow754updated 2 months ago