원클릭으로
versioning
Use when adding API versioning or managing multiple API versions in a .NET project.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Use when adding API versioning or managing multiple API versions in a .NET project.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Use when adding caching to .NET APIs or optimizing response times with distributed cache, output cache, or ETags.
Use when configuring API response formats, custom formatters, or Accept header handling.
Use when building controller-based REST APIs with action results, model binding, or MediatR integration.
Use when creating RESTful API controllers with MediatR dispatch and ProblemDetails error responses.
Use when designing gRPC services, proto files, or adding gRPC-Web or JSON transcoding.
Use when building minimal API endpoints with route groups, filters, or TypedResults.
| name | versioning |
| description | Use when adding API versioning or managing multiple API versions in a .NET project. |
| metadata | {"category":"api","agent":"api-designer","when-to-use":"When configuring API versioning strategies or sunset policies"} |
/api/v1/orders) is the most common and recommended// Program.cs
builder.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;
});
[ApiController]
[Route("api/v{version:apiVersion}/orders")]
[ApiVersion("1.0")]
[ApiVersion("2.0")]
public sealed class OrdersController(ISender sender) : ControllerBase
{
[HttpGet]
[MapToApiVersion("1.0")]
public async Task<ActionResult<List<OrderV1Response>>> GetOrdersV1(
CancellationToken ct)
{
var result = await sender.Send(new ListOrdersV1Query(), ct);
return Ok(result);
}
[HttpGet]
[MapToApiVersion("2.0")]
public async Task<ActionResult<PagedList<OrderV2Response>>> GetOrdersV2(
[FromQuery] OrderFilter filter, CancellationToken ct)
{
var result = await sender.Send(new ListOrdersV2Query(filter), ct);
return Ok(result);
}
}
// Or separate controllers per version
[ApiController]
[Route("api/v{version:apiVersion}/orders")]
[ApiVersion("1.0", Deprecated = true)]
public sealed class OrdersV1Controller : ControllerBase { }
[ApiController]
[Route("api/v{version:apiVersion}/orders")]
[ApiVersion("2.0")]
public sealed class OrdersV2Controller : ControllerBase { }
var versionSet = app.NewApiVersionSet()
.HasApiVersion(new ApiVersion(1, 0))
.HasApiVersion(new ApiVersion(2, 0))
.ReportApiVersions()
.Build();
var v1 = app.MapGroup("/api/v{version:apiVersion}")
.WithApiVersionSet(versionSet);
v1.MapGet("/orders", GetOrdersV1)
.MapToApiVersion(new ApiVersion(1, 0));
v1.MapGet("/orders", GetOrdersV2)
.MapToApiVersion(new ApiVersion(2, 0));
builder.Services.AddApiVersioning(options =>
{
options.ApiVersionReader = new HeaderApiVersionReader("X-Api-Version");
});
// Client sends: X-Api-Version: 2.0
builder.Services.AddApiVersioning(options =>
{
options.ApiVersionReader = new QueryStringApiVersionReader("api-version");
});
// Client requests: /api/orders?api-version=2.0
builder.Services.AddApiVersioning(options =>
{
options.ApiVersionReader = ApiVersionReader.Combine(
new UrlSegmentApiVersionReader(),
new HeaderApiVersionReader("X-Api-Version"),
new QueryStringApiVersionReader("api-version"));
});
builder.Services.AddApiVersioning(options =>
{
options.Policies.Sunset(1.0)
.Effective(new DateTimeOffset(2025, 6, 1, 0, 0, 0, TimeSpan.Zero))
.Link("https://docs.{Company}.com/api/migration-guide")
.Title("v1 to v2 Migration Guide")
.Type("text/html");
});
// Response header: Sunset: Sat, 01 Jun 2025 00:00:00 GMT
// Response header: Link: <https://docs.{Company}.com/api/migration-guide>; ...
builder.Services.AddOpenApi("v1");
builder.Services.AddOpenApi("v2");
// Each document at /openapi/v1.json and /openapi/v2.json
app.MapOpenApi();
Asp.Versioning package reference in .csprojAddApiVersioning in Program.cs[ApiVersion] attributes on controllersv{version:apiVersion} in route templatesAsp.Versioning.Http (minimal API) or Asp.Versioning.Mvc.ApiExplorer (controllers)AddApiVersioning with default version and reader[ApiVersion] to existing controllers (start with "1.0")| Strategy | Pros | Cons | Use When |
|---|---|---|---|
| URL segment | Visible, cacheable, simple | Version in URL | Default choice |
| Header | Clean URLs | Hidden, harder to test | Internal APIs |
| Query string | Easy to add | Pollutes query params | Legacy compat |