Api Versioning

codewithmukesh/dotnet-claude-kit/skills/api-versioning

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

API versioning strategies for ASP.NET Core. Covers Asp.Versioning library, URL segment, header, and query string strategies, version deprecation, and OpenAPI integration. Load this skill when adding versioning to an API, evolving an API with breaking changes, or when the user mentions "API version", "versioning", "v1/v2", "Asp.Versioning", "deprecation", "breaking change", or "backward compatibility".

Instructions onlySoftware Development
AI-generated overview

Guidance on API versioning strategies for ASP.NET Core, covering Asp.Versioning, URL, header and query versioning, and deprecation.

What it does
This skill provides reference guidance for adding versioning to ASP.NET Core APIs. It explains the Asp.Versioning library setup, URL segment, header and query string strategies, version deprecation, and OpenAPI integration, with code examples and a decision guide. It also lists anti-patterns such as versioning individual endpoints or defaulting to query string versioning.
When to use it
Use it when adding versioning to an API, evolving an API with breaking changes, or when the user mentions API version, versioning, v1/v2, Asp.Versioning, deprecation, breaking change, or backward compatibility.
Requirements
No scripts or tools are required; it is instructions only. The examples assume an ASP.NET Core project using the Asp.Versioning library.

API Versioning

Core Principles

  1. Version from day one — Adding versioning later is painful. Start with a version in the URL even if you only have v1.
  2. URL segment versioning is the default — /api/v1/orders is the most discoverable and cache-friendly strategy.
  3. Never break existing versions — Add a new version for breaking changes. Deprecate the old version with a timeline.
  4. Version the API, not individual endpoints — All endpoints in a version group share the same version number.

Patterns

Setup with Asp.Versioning

csharp
// Program.csbuilder.Services.AddApiVersioning(options =>{    options.DefaultApiVersion = new ApiVersion(1, 0);    options.AssumeDefaultVersionWhenUnspecified = true;    options.ReportApiVersions = true;    options.ApiVersionReader = new UrlSegmentApiVersionReader();}).AddApiExplorer(options =>{    options.GroupNameFormat = "'v'VVV";    options.SubstituteApiVersionInUrl = true;});

URL Segment Versioning (Recommended)

csharp
var v1 = app.NewApiVersionSet()    .HasApiVersion(new ApiVersion(1, 0))    .Build();
var v2 = app.NewApiVersionSet()    .HasApiVersion(new ApiVersion(2, 0))    .Build();
app.MapGroup("/api/v{version:apiVersion}/orders")    .WithApiVersionSet(v1)    .WithTags("Orders")    .MapOrderEndpointsV1();
app.MapGroup("/api/v{version:apiVersion}/orders")    .WithApiVersionSet(v2)    .WithTags("Orders")    .MapOrderEndpointsV2();

Header Versioning (Alternative)

csharp
options.ApiVersionReader = new HeaderApiVersionReader("X-Api-Version");
// Client sends: X-Api-Version: 2.0

Deprecating a Version

csharp
var v1 = app.NewApiVersionSet()    .HasDeprecatedApiVersion(new ApiVersion(1, 0))    .HasApiVersion(new ApiVersion(2, 0))    .Build();
// Response headers will include: api-deprecated-versions: 1.0

Version-Specific Endpoint Groups

csharp
public static class OrderEndpointsV1{    public static RouteGroupBuilder MapOrderEndpointsV1(this RouteGroupBuilder group)    {        group.MapGet("/{id:guid}", GetOrderV1);        group.MapPost("/", CreateOrderV1);        return group;    }
    private static async Task<Results<Ok<OrderResponseV1>, NotFound>> GetOrderV1(        Guid id, ISender sender, CancellationToken ct)    {        // V1 response shape        var result = await sender.Send(new GetOrder.Query(id), ct);        return result.IsSuccess            ? TypedResults.Ok(result.Value.ToV1())            : TypedResults.NotFound();    }}
public static class OrderEndpointsV2{    public static RouteGroupBuilder MapOrderEndpointsV2(this RouteGroupBuilder group)    {        group.MapGet("/{id:guid}", GetOrderV2);        group.MapPost("/", CreateOrderV2);        return group;    }
    private static async Task<Results<Ok<OrderResponseV2>, NotFound>> GetOrderV2(        Guid id, ISender sender, CancellationToken ct)    {        // V2 response shape — includes new fields        var result = await sender.Send(new GetOrder.Query(id), ct);        return result.IsSuccess            ? TypedResults.Ok(result.Value.ToV2())            : TypedResults.NotFound();    }}

Anti-patterns

Don't Version Individual Endpoints

csharp
// BAD — inconsistent versioning within a groupapp.MapGet("/api/v1/orders", ListOrdersV1);app.MapGet("/api/v2/orders/{id}", GetOrderV2); // V2 only for this endpoint?
// GOOD — version the entire groupapp.MapGroup("/api/v1/orders").MapOrderEndpointsV1();app.MapGroup("/api/v2/orders").MapOrderEndpointsV2();

Don't Use Query String Versioning as Default

csharp
// BAD for REST APIs — version hidden in query string, not cache-friendlyGET /api/orders?api-version=2.0
// GOOD — version in URL, discoverable and cacheableGET /api/v2/orders

Decision Guide

ScenarioRecommendation
New public APIURL segment versioning from day one
Internal API between servicesHeader versioning (cleaner URLs)
Breaking response shape changeNew version
Adding new optional fieldsSame version (backwards compatible)
Deprecating a versionMark deprecated, set sunset date, document migration path

Source and attribution

Source:codewithmukesh/dotnet-claude-kitinskills/api-versioningat 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