Asp.Versioning 10.0 наконец-то дружит со встроенным OpenAPI в .NET 10
Asp.Versioning 10.0 — это первый релиз, нацеленный на .NET 10 и новый пайплайн Microsoft.AspNetCore.OpenApi. Руководство Сандера тен Бринке от 23 апреля показывает, как зарегистрировать отдельный документ OpenAPI на каждую версию API с помощью WithDocumentPerVersion().
Когда ASP.NET Core 9 заменил Swashbuckle на встроенный генератор Microsoft.AspNetCore.OpenApi, не хватило одной склеивающей детали: не было чистого способа подключить новый пайплайн к Asp.Versioning и выдавать отдельный документ для каждой версии. Исправление приехало на прошлой неделе. Пост Сандера тен Бринке от 23 апреля в .NET Blog — это официальное руководство “делайте вот так”, и он идёт в паре с первыми пакетами Asp.Versioning, нацеленными на .NET 10.
Какие пакеты изменились
Для minimal API вы теперь подключаете три пакета, все актуальные на апрель 2026:
Asp.Versioning.Http10.0.0Asp.Versioning.Mvc.ApiExplorer10.0.0Asp.Versioning.OpenApi10.0.0-rc.1
Для контроллеров замените Asp.Versioning.Http на Asp.Versioning.Mvc 10.0.0. Пакет OpenApi делает всю настоящую работу: он соединяет модель API explorer, которую библиотека версионирования и так производит, с пайплайном трансформеров документа, которого ожидает Microsoft.AspNetCore.OpenApi. До этого релиза приходилось вручную писать трансформер, который читает IApiVersionDescriptionProvider и фильтрует операции по документу. Теперь этот код в коробке.
Один документ на версию, в три строки
Регистрация сервисов не меняется по сравнению с историей версионирования до OpenAPI, добавляется только один вызов .AddOpenApi():
builder.Services.AddApiVersioning()
.AddApiExplorer(options =>
{
options.GroupNameFormat = "'v'VVV";
})
.AddOpenApi();
На стороне endpoint появляется новое расширение:
app.MapOpenApi().WithDocumentPerVersion();
WithDocumentPerVersion() перечисляет всё, что возвращает DescribeApiVersions(), и регистрирует по одному документу на каждую версию. Вы открываете /openapi/v1.json и /openapi/v2.json и получаете ровно те операции, которые относятся к каждой версии, без общих ID операций и без дублированных схем, протекающих между документами. И Scalar (app.MapScalarApiReference()), и Swagger UI (app.UseSwaggerUI()) автоматически обнаруживают документы через того же провайдера описаний версий API, так что переключатель в браузере подключается бесплатно.
Версионированные группы маршрутов
Для minimal API сторона маршрутов остаётся компактной. Вы один раз объявляете версионированный API и навешиваете на него группы для каждой версии:
var usersApi = app.NewVersionedApi("Users");
var usersV1 = usersApi.MapGroup("api/users").HasApiVersion("1.0");
var usersV2 = usersApi.MapGroup("api/users").HasApiVersion("2.0");
usersV1.MapGet("", () => Results.Ok(new { shape = "v1" }));
usersV2.MapGet("", () => Results.Ok(new { shape = "v2" }));
Имя Users становится группой API; HasApiVersion — это то, что API explorer читает, чтобы решить, к какому документу OpenAPI принадлежит каждый endpoint.
Почему это важно прямо сейчас
Если вы начали новое приложение на ASP.NET Core 9 или 10 и принципиально пропустили Swashbuckle, единственное, что тянуло вас обратно, — это версионирование. С Asp.Versioning.OpenApi 10.0.0-rc.1 этот аварийный люк закрывается. Суффикс RC — единственная причина подождать: поверхность API именно та, что выйдет в релизе, и команда целится в GA вместе с поездом обслуживания .NET 10. Полный пример живёт в репозитории Сандера, на который ссылается пост, и его стоит клонировать перед следующим разом, когда вы потянетесь к самописному трансформеру.
Comments
Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.