Swagger — это не зависящая от языка спецификация для описания REST API. Она позволяет компьютерам и пользователям лучше понять возможности REST API без прямого доступа к исходному коду. Точнее позволяла, ведь Microsoft удаляет встроенную поддержку Swagger (Swashbuckle) в .NET 9 из-за проблем с обслуживанием и перехода на встроенную поддержку OpenAPI. Вместо этого в качестве альтернативного инструмента для документации API предлагается Scalar с простой интеграцией и настраиваемыми функциями, включая схемы аутентификации.
Почему удален Swagger?
Команда разработчиков ASP.NET Core решила удалить встроенную поддержку Swagger (Swashbuckle) из .NET 9 по нескольким причинам:
- Проблемы с поддержкой: проект Swashbuckle больше не поддерживается его владельцем. Проблемы не устраняются и не решаются, и не было официального выпуска для .NET 8.
- Эволюция ASP.NET Core: с момента появления поддержки Swagger в .NET 5 ASP.NET Core значительно изменился. Теперь он включает встроенную поддержку метаданных, необходимых для описания веб-API, что снижает потребность во внешних инструментах.
- Сосредоточенность на OpenAPI: команда стремится сделать OpenAPI более интегрированной функцией в ASP.NET Core. Они планируют расширить возможности Microsoft.AspNetCore.OpenApi для создания документов OpenAPI без использования внешних пакетов.
- Альтернативные инструменты: теперь Visual Studio предлагает встроенную поддержку для файлов .http и новый инструмент Endpoints Explorer, предоставляющий альтернативные способы изучения, тестирования и отладки API.
- Инновации, ориентированные на сообщество: удаляя зависимость по умолчанию, команда поощряет использование и разработку различных инструментов OpenAPI, которые могут лучше соответствовать конкретным потребностям проекта.
Новый альтернативный инструмент — Scalar
Scalar — это интерактивный инструмент для создания документации API, который работает с документами OpenAPI/Swagger. Вы можете получить более подробную информацию здесь, а если потребуется посмотреть код, то можно глянуть сюда.
Давайте попробуем добавить Scalar в свежесозданный проект из шаблона. Для начала необходимо установить Nuget-пакет:
dotnet add package Scalar.AspNetCore
И добавим соответствующее пространство имён:
using Scalar.AspNetCore;
Добавьте следующее в Program.cs
на основе вашего генератора OpenAPI. Для .Net 9 нужно использовать Microsoft.AspNetCore.OpenApi
:
builder.Services.AddOpenApi();
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
app.MapScalarApiReference();
}
Для .Net 8 есть два варианта. Первый это использовать Swashbuckle
:
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
if (app.Environment.IsDevelopment())
{
app.UseSwagger(options =>
{
options.RouteTemplate = "/openapi/{documentName}.json";
});
app.MapScalarApiReference();
}
Альтернативный вариант использоваться NSwag
:
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddOpenApiDocument();
if (app.Environment.IsDevelopment())
{
app.UseOpenApi(options =>
{
options.Path = "/openapi/{documentName}.json";
});
app.MapScalarApiReference();
}
В целом готово. Для простейшего сценария использования этого будет достаточно — в большинстве случаев настроек по умолчанию хватит, а страницу с информацией мы увидим по адресу /scalar/v1
, где v1
имя файла по умолчанию.
Пример кода
Давайте посмотрим на то как выглядит это на примере. Добавим к стандартному решению ещё один эндпоинт app.MapGet("/", () => "Hello world!")
, чтобы их у нас было больше одного. В результате мы получим вот такой код:
using Scalar.AspNetCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenApi();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.MapScalarApiReference();
app.MapOpenApi();
}
app.UseHttpsRedirection();
var summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
app.MapGet("/", () => "Hello world!");
app.MapGet("/weatherforecast", () =>
{
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
return forecast;
})
.WithName("GetWeatherForecast");
app.Run();
record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
Посмотрим на результат по адресу http(s)://localhost:{port}/scalar/v1:


Настройка конфигурации
Метод MapScalarApiReference
принимает необязательный параметр options
, который можно использовать для настройки Scalar с помощью Fluent API или синтаксиса инициализации объектов:
app.MapScalarApiReference(options =>
{
// Fluent API
options
.WithTitle("Custom API")
.WithSidebar(false);
// Инициализация объекта
options.Title = "Custom API";
options.ShowSidebar = false;
});
Разумеется, использовать его не обязательно (на то это и необязательный параметр :) ) и настроек по умолчанию хватит для нормальной работы, но если хочется навести красоту, то почему бы и нет?
Настройка авторизации
В целом всё что нужно для pet-project уже посмотрели. Но что если мы хотим потыкать что-то с аутентификацией? В таком случае нам может потребоваться добавить один из вариантов аутентификации — включая API-ключ, OAuth, HTTP Basic и Bearer, позволяя предварительно заполнять некоторые данные для аутентификации.
Ключ API
Чтобы упростить использование ключа API, вы можете предоставить токен:
app.MapScalarApiReference(options =>
{
// Fluent API
options
.WithPreferredScheme("ApiKey") // Имя схемы безопасности из документа OpenAPI
.WithApiKeyAuthentication(apiKey =>
{
apiKey.Token = "your_api_key";
});
// Инициализация объекта
options.Authentication = new ScalarAuthenticationOptions
{
PreferredSecurityScheme = "ApiKey", // Имя схемы безопасности из документа OpenAPI
ApiKey = new ApiKeyOptions
{
Token = "your_api_key"
}
}
});
OAuth
Аналогичным образом вы можете предварительно заполнить поля OAuth, такие как идентификатор клиента и области действия:
app.MapScalarApiReference(options =>
{
options
.WithPreferredScheme("OAuth2") // Имя схемы безопасности из документа OpenAPI
.WithOAuth2Authentication(oauth =>
{
oauth.ClientId = "your_client_id";
oauth.Scopes = ["profile"];
});
});
HTTP Basic/Bearer
Поля аутентификации HTTP Basic или с использованием Bearer-токена также можно легко заполнить заранее:
app.MapScalarApiReference(options =>
{
// HTTP Basic
options
.WithPreferredScheme("Basic") // Имя схемы безопасности из документа OpenAPI
.WithHttpBasicAuthentication(basic =>
{
basic.Username = "your_username";
basic.Password = "your_password";
});
// Bearer
options
.WithPreferredScheme("Bearer") // Имя схемы безопасности из документа OpenAPI
.WithHttpBearerAuthentication(bearer =>
{
bearer.Token = "your_bearer_token";
});
});
Использование OpenAPI документа
Для тех, кто придерживается Design API First подхода в разработке также есть возможность использовать OpenAPI документ. Scalar ожидает, что он будет находиться по адресу /openapi/{documentName}.json
, соответствующему маршруту встроенного генератора .NET OpenAPI в пакете Microsoft.AspNetCore.OpenApi
. Если документ находится в другом месте, укажите путь с помощью свойства OpenApiRoutePattern
:
app.MapScalarApiReference(options =>
{
options.WithOpenApiRoutePattern("/{document_path}/{documentName}.json");
// или
options.OpenApiRoutePattern = "/{document_path}/{documentName}.json";
});
Заключение
Не смотря на то, что Swagger сослужил нам хорошую службу пришло время с ним прощаться. Ему на смену пришёл Scalar, который также позволяет создавать, документировать и проверять API. И теперь вы готовы к его использованию :)