С выходом .NET 9 пакет Swashbuckle.AspNetCore выпилили из шаблона Web API. Это означает, что при создании нового приложения ASP.NET Core Web API у нас больше нет привычного зеленого пользовательского интерфейса Swagger для тестирования endpoint-ов. В статье — краткий разбор, почему это произошло, и обзор альтернативы Scalar.
Что не так со Swagger в .NET
Раньше, чтобы создать документацию OpenAPI в ASP.NET Core, многие пользовались Swashbuckle. Это было настолько популярным решением, что Microsoft включила его в дефолтные шаблоны Web API.
Но в какой-то момент основные разработчики Swashbuckle покинули проект и начались трудности: копился техдолг, и запоздалая поддержка .NET 8 привела к проблемам совместимости. Тогда Microsoft засомневались, что продукт будет развиваться и вовремя поддерживать новые версии .NET.
Чтобы перестраховаться, Microsoft отказались от Swashbuckle и сделали собственное решение — ведь поддерживать и интегрировать своё проще, чем чужое. Теперь при создании решения в .NET 9 из шаблона Web API в проекте будет пакет Microsoft.AspNetCore.OpenApi.
С пакетом OpenApi разработчики получили больше собственных способов тестирования и документирования API. Например, теперь есть поддержка файлов .http в Visual Studio и Endpoints Explorer. Это делает Swagger UI менее необходимым.
Прочитать мнение Microsoft по этому поводу
А что, Swagger больше совсем не работает?
Пакет Swashbuckle.AspNetCore доступен, его можно установить, и нет предпосылок к тому, что это изменится. Проблема в том, что проект развивается крайне медленно и не успевает за новыми фичами ASP.NET Core.
Но для тех, кто хочет продолжать использовать Swagger, есть целых два способа. Первый — заменить пакет Microsoft.AspNetCore.OpenApi на Swashbuckle.AspNetCore. Затем добавить привычные вызовы.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSwaggerGen();
var app = builder.Build();
app.UseSwagger();
app.UseSwaggerUI();
app.MapGet("/", => "Hello World!");
app.Run();
Тогда OpenAPI-спецификация будет генерироваться с помощью библиотеки Swashbuckle как и раньше.
Второй способ — оставить пакет Microsoft.AspNetCore.OpenApi для генерации спецификации, а подключить только Swagger UI.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenApi();
var app = builder.Build();
app.MapOpenApi();
app.UseSwaggerUI(o =>
o.SwaggerEndpoint("/openapi/v1.json", "v1"));
app.MapGet("/", => "Hello World!");
app.Run();
В этом случае при вызове UseSwaggerUI важно указать путь для файла со спецификацией.
Немного про настройку OpenAPI
Генерацию спецификации через пакет OpenApi можно гибко настраивать, как и при Swagger. Вот основные значения, которые можно указать:
builder.Services.AddOpenApi(options =>
{
options.AddDocumentTransformer((document, context, cancellationToken) =>
{
document.Info.Version = "Версия документа OpenAPI";
document.Info.Title = "Заголовок";
document.Info.Description = "Описание";
document.Info.TermsOfService = new Uri("https://mycompany.com/terms");
document.Info.Contact = new OpenApiContact
{
Name = "Ivan Ivanov",
Email = "iivanov@mycompany.com",
Url = new Uri("https://habr.com/")
};
document.Info.License = new OpenApiLicense
{
Name = "MIT License",
Url = new Uri("https://opensource.org/licenses/MIT")
};
//Информация о подключении к целевому серверу
document.Servers.Add(new OpenApiServer
{
Url = "https://my.app.com/v1",
Description = "Описание для хоста"
});
return Task.CompletedTask;
});
});
Можно настроить метаданные OpenAPI для endpoint-ов Minimal API в ASP.NET Core:
app.MapGet("/{answer}",
(
[Description("Your answer.")]
[DefaultValue("42")]
string answer
) => Results.Ok(new { Message = $"Answer: {answer}!" }))
.WithName("GetAnswer") // Идентификатор операции
.WithSummary("Answer to the Question.") // Заголовок
.WithDescription("Answer to the Ultimate Question of Life, the Universe, and Everything.") // Полное описание
.WithTags("DeepThought") // Теги для категоризации
.Produces<object>(200) // Статус ответа 200 и возвращаемый тип данных
.Produces(400) // Статус ответа 400
.ProducesProblem(500) // Статус ответа 500 при неуспешной операции
.RequireAuthorization(); // Необходимость авторизации
Scalar как альтернатива SwaggerUI
Scalar — это платформа с открытым исходным кодом для документирования и взаимодействия с RESTful API. Он поддерживает спецификации OpenAPI и Swagger, так что его можно легко интегрировать в большинство существующих решений.
Счётчик скачивания пакетов и больше 10K звезд на GitHub наводят на мысль, что в сообществе .NET его всё чаще выбирают как альтернативу SwaggerUI.
У Scalar более современный и удобный дизайн, его проще настраивать. Есть мощная функция генерации клиентского кода для различных языков программирования. А ещё с ним легко добавлять или изменять файлы cookie, заголовки и параметры при работе с запросами.
Начало работы со Scalar
Первым делом необходимо добавить nuget-пакет Scalar.AspNetCore. А затем подключить Scalar в Program.cs:
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
app.MapScalarApiReference();
}
Ещё можно изменить файл launchSettings.json, чтобы Scalar UI запускался сразу после старта приложения.
"https": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "scalar/v1",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
Этого достаточно, чтобы при запуске приложения по пути /scalar/v1 открывалась соответствующая страница.

Слева отображаются все сгруппированные по тегам endpoint-ы и все модели. На моём скриншоте виден единственный endpoint и относящаяся к нему модель ProblemDetails. На основной части страницы отображается информация о приложении, полученная из OpenAPI-схемы. Есть поиск с удобной навигацией по endpoint-ам и моделям.

Если выбрать endpoint из списка на основной странице или на странице поиска, отобразится описание запроса с параметрами и коды ответа.

Чтобы отправить запрос в приложение, нужно нажать Test Request.

Слева на странице можно посмотреть и изменить параметры запроса, заголовки и куки. В поле Code Snippet формируется код запроса с актуальными параметрами. По дефолту выбрана системная программа Curl, но в выпадающем списке спрятано много языков программирования — в том числе C#.
Send отправляет запрос, а справа отображается ответ. В целом вся эта страница по функционалу напоминает Postman.
Конфигурация Scalar
Сильная сторона Scalar — это количество возможных настроек. Изменить можно тему, переключатели темного режима и многое другое.
app.MapScalarApiReference(options =>
{
options
.WithTheme(ScalarTheme.Kepler)
.WithDarkModeToggle(true)
.WithClientButton(true);
});
Про темы. Сейчас много готовых тем, но если хочется, можно полностью изменить внешний вид страницы, используя CSS. Прочитать
Про работу с аутентификацией. Scalar поддерживает различные схемы аутентификации, включая API Key, OAuth2 и HTTP Basic/Bearer. Это позволяет предустанавливать определённые данные аутентификации. Пример настройки аутентификации OAuth2:
app.MapScalarApiReference(options => options
.AddPreferredSecuritySchemes("OAuth2")
.AddOAuth2Authentication("OAuth2", scheme =>
{
scheme.Flows = new ScalarFlows
{
AuthorizationCode = new AuthorizationCodeFlow
{
ClientId = "your-client-id",
RedirectUri = "https://your-app.com/callback"
},
ClientCredentials = new ClientCredentialsFlow
{
ClientId = "your-client-id",
ClientSecret = "your-client-secret"
}
};
scheme.DefaultScopes = ["profile", "email"];
})
);
Полная информация о подключении различных типов аутентификации и о настройке Scalar в целом — в официальной документации.
Итог
Мне Scalar понравился. Из плюсов — простое подключение и начало работы, гибкая настройка, хорошая документация с примерами. Ещё большой плюс — активное развитие кодовой базы. По функционалу Scalar сильно выигрывает у SwaggerUI.
Из минусов отмечу непривычный после Swagger-а интерфейс, который скорее напоминает Postman на минималках. И уверен, что все имеющиеся функции нужны далеко не в каждом проекте.
Комментарии (6)
posledam
27.05.2025 06:37Но в какой-то момент основные разработчики Swashbuckle покинули проект и начались трудности: копился техдолг, и запоздалая поддержка .NET 8 привела к проблемам совместимости.
Действительно, такой период был. Но сейчас проект активно развивается, все новые фичи платформы поддерживаются, релизы выпускаются. Нет причин для беспокойства.
Scalar безусловно проект интересный, но стоит обратить внимание, что это коммерческая разработка, где Scalar .NET — не отдельный самостоятельный репозиторий, а интеграционный пакет. В связи с этим есть определённые риски, которые надо учитывать.
m3ta10ph0b Автор
27.05.2025 06:37Нет причин для беспокойства.
Как верно замечено — такой период был и может повториться. Потому согласен, именно сейчас нет причин для беспокойства, но всегда хорошо иметь альтернативный вариант в загашнике, не правда ли?
В связи с этим есть определённые риски
Тоже согласен, риски всегда есть. Так что хорошо, когда есть из чего выбрать.
На самом деле я не призываю срочно переходить со Swagger UI на Scalar. Да и не срочно тоже. Это скорее обзор на вполне себе достойную рабочую альтернативу, которую хорошо иметь на примете.
posledam
27.05.2025 06:37Обзор отличный, мой коммент не критика, а уточнение. Я бы сделал больше акцент на OpenApi от Microsoft, на который стоит переходить, а UI вообще можно и оба сразу добавить :)
m3ta10ph0b Автор
27.05.2025 06:37Да, я понял - и я со всем согласен, как я и написал выше.
а UI вообще можно и оба сразу добавить :)
Про это кстати тоже думал и ради эксперимента добавлял. Это может быть полезно при переходе с одного на другое на "боевом" проекте, чтобы кто-то для уже начинал осваивать новый интерфейс, но при этом оставалась возможность работать с привычным
Спасибо за интерес к теме!
Vitimbo
Имхо, большого смысла прыгать со сваггера на это нет, но при старте проекта вполне можно рассмотреть как вариант. Понравилось, что можно сразу получить от него готовый fetch для js.
m3ta10ph0b Автор
Я тоже так считаю. Пока нет смысла, но хорошо, что есть возможность быстро переключиться. Допустим, в OpenAPI появится что-то очень нужное, а сваггер не будет это поддерживать.