Документирование API. Основы Swagger

До сих пор мы разрабатывали нашы проекты ASP.NET Core Web API, особенно не вдаваясь в вопросы документирования тех или иных возможностей и функций приложения. Между тем, документирование API – это, едва ли не самая важная часть работы над проектом, если вы планируете его распространять среди широкого круга пользователей. Именно документация API позволяет потенциальным и уже имеющимся пользователям разобраться с тем, как работает ваш API, какие методы предоставляет, как его эффективно использовать и так далее.

Что такое Swagger и OpenAPI?

OpenAPI — это не зависящая от языка спецификация для описания REST API. В 2015 году OpenAPI Initiative был передан проект под названием Swagger – инструментарий для описания API с использованием спецификации OpenAPI. На сегодняшний день эти два названия – OpenAPI и Swagger стали на столько тесно связанными, что их можно даже назвать взаимозаменяемыми. Даже в разделе официального сайта Microsoft, посвященному работе со Swagger первое же предложение начинается со слов «Swagger (OpenAPI) – это спецификация…», хотя, если быть предельно строгими к описанию, то спецификацией является OpenAPI, а Swagger – всего лишь инструмент для работы в соответствии с этой спецификацией, хотя и довольно мощный, и удобный.

Nuget-пакеты для Swagger

В ASP.NET Core существует две реализации OpenAPI – это Swashbuckle и NSwag. Причем, по умолчанию, при создании проекта ASP.NET Core Web API используется именно первая реализация.

Swagger в ASP.NET Core использует три компонента:

  • AspNetCore.Swagger – содержит объектную модель Swagger и промежуточное программное обеспечение для предоставления объектов SwaggerDocument в формате JSON.
  • AspNetCore.SwaggerGen – генератор Swagger, который создает объекты SwaggerDocument непосредственно из наших маршрутов, контроллеров и моделей.
  • AspNetCore.SwaggerUI – встроенная версия инструмента пользовательского интерфейса Swagger. Он интерпретирует Swagger JSON для создания богатых и настраиваемых возможностей описания функций веб-API.

Для того, чтобы воспользоваться всеми этими компонентами, нам необходимо установить nuget-пакет Swashbuckle.AspNetCore. После установки пакета в «Обозревателе решений» Visual Studio проект будет выглядеть следующим образом

Настройка Swagger в приложении

Настроим работу Swagger в нашем приложении. Для этого перейдем в файл Program.cs и внесем в него следующие изменения

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

builder.Services.AddSwaggerGen();

var app = builder.Build();

app.UseHttpsRedirection();

app.UseSwagger();
app.UseSwaggerUI();

app.UseAuthorization();

app.MapControllers();

app.Run();

Здесь мы подключаем необходимый сервис для генерации документов Swagger

builder.Services.AddSwaggerGen();

и встраиваем два компонента middleware в конвейер обработки запросов.

app.UseSwagger();
app.UseSwaggerUI();

При этом мы оставляем все настройки Swagger со значениями по умолчанию. Теперь запустим приложение, откроем любой браузер и перейдем по адресу https://localhost:[port]/swagger/. В результате вы увидите Swagger UI, где в удобном виде будут сгруппированы все методы API, которые мы добавляли в наше приложение

Методы API сгруппированы по контроллерам. Также, в этом же окне представлены и все схемы данных, которые используются в приложении

Конечные точки Swagger

На данный момент пользовательский интерфейс Swagger доступен по адресу https://localhost:[port]/swagger/, а если вы перейдете по адресу https://localhost:[port]/swagger/v1/swagger.json, то увидите сформированный документ Swagger (см. рис):

Этот документ содержит описание всех методов API, созданное с использованием спецификации OpenAPI 3.0.1. При необходимости мы можем менять как расположение документа Swagger, так и адрес расположения пользовательского интерфейса. Например

app.UseSwaggerUI(options =>
{
    options.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
    options.RoutePrefix = string.Empty;
});

Здесь в методе расширения UseSwaggerUI() мы добавили настройки – конечную точку расположения документа Swagger

options.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");

А также указали для свойства RoutePrefix пустую строку, которая означает, что пользовательский интерфейс Swagger будет доступен по адресу https://localhost:[port].

Общие сведения об API

Также мы можем добавить общие сведения об API, используя настройки сервиса Swagger

builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo()
    {
        Description = "Web API на основе контроллеров",
        Title = "Web API v1",
        Version = "v1",
        Contact = new Microsoft.OpenApi.Models.OpenApiContact()
        {
            Email = "admin@webdelphi.ru",
            Name = "Vlad",
            Url = new Uri("https://csharp.webdelphi.ru")
        }
    });
});

Здесь мы добавили версия API, небольшое описание и контактные данные. В интерфейсе Swagger эта информация будет выглядеть следующим образом

 

Настройка авторизации

Для того, чтобы использовать механизмы авторизации при тестировании запросов к API в Swagger необходимые настройки авторизации также добавляются при регистрации сервиса в контейнере зависимостей. Например, добавим авторизацию с использованием JWT-токенов, которую мы создавали ранее для нашего приложения

builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo()
    {
        Description = "Web API на основе контроллеров",
        Title = "Web API v1",
        Version = "v1",
        Contact = new Microsoft.OpenApi.Models.OpenApiContact()
        {
            Email = "admin@webdelphi.ru",
            Name = "Vlad",
            Url = new Uri("https://csharp.webdelphi.ru")
        }
    });

    //настройки авторизации
    options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
    {
        Description = "Скопируйте сюда ключ доступа и добавьте в начале строку \"Bearer\"",
        In = ParameterLocation.Header,
        Scheme = "Bearer",
        Type = SecuritySchemeType.ApiKey,
        Name = "Authorization"
    });

    options.AddSecurityRequirement(new OpenApiSecurityRequirement()
    {
       { 
            new OpenApiSecurityScheme {
                 Reference = new OpenApiReference()
                 {
                     Type = ReferenceType.SecurityScheme,
                     Id = "Bearer"
                 },
                Name = "Bearer",
            },
             new List<string>()
       }
    });
});

Здесь мы определяем способ авторизации

options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
{
    Description = "Скопируйте сюда ключ доступа и добавьте в начале строку \"Bearer\"",
    In = ParameterLocation.Header,
    Scheme = "Bearer",
    Type = SecuritySchemeType.ApiKey,
    Name = "Authorization"
});

указав место расположения ключа доступа (ParameterLocation.Header – заголовок), имя схемы авторизации, которое должно использоваться в заголовке («Bearer»), тип схемы безопасности (SecuritySchemeType.ApiKey), имя заголовка в котором будет размещаться ключ безопасности («Authorization»), а также подсказку для клиента API. И далее мы добавили объект, определяющий требования безопасности.

options.AddSecurityRequirement(new OpenApiSecurityRequirement()
{
   { 
        new OpenApiSecurityScheme {
             Reference = new OpenApiReference()
             {
                 Type = ReferenceType.SecurityScheme,
                 Id = "Bearer"
             },
            Name = "Bearer",
        },
         new List<string>()
   }
});

Здесь имя объекта полностью соответствует имени схемы, которое мы определили выше при описании способа авторизации. Теперь, если запустить приложение и открыть в браузере Swagger UI, то мы должны увидеть следующее изменение в интерфейсе

Для того, чтобы авторизоваться в Swagger UI для выполнения запросов к API, необходимо нажать кнопку Authorize и ввести ключ доступа:

После этого можно выбрать в списке какой-либо метод API, требующий авторизации и выполнить его.

Добавление описания методов API

Swagger – это не столько инструмент для тестирования методов API, сколько инструмент для документирования API. Однако, на данный момент, из всей документации по API у нас только его краткое описание. Исправим этот момент, позволив Swagger создавать документацию по API, используя XML-комментарии в коде. Для этого перейдем в свойства проекта в Visual Studio, кликнув правой кнопкой мыши по его названию в обозревателе решений

В разделе «Сборка —> Выходные данные» необходимо установить флажок напротив пункта «Файл документации» и указать имя XML-файла в котором будет храниться документация по API

Теперь нам необходимо настроить Swagger на использование этого файла. Сделать это можно так же, как и настройку авторизации – при добавлении сервиса

builder.Services.AddSwaggerGen(options =>
{
    //добавление общих сведений о приложении

    //тут код настройки общих сведений

    //настройки авторизации

    //тут код настройки авторизации

    //настраиваем Swagger на чтение XML-комментариев
    var xmlPath = Path.Combine(Environment.CurrentDirectory, "documentation.xml");
    options.IncludeXmlComments(xmlPath);
});

Чтобы не повторять уже рассмотренный выше код настройки сервиса, здесь показаны только новые строки кода, в которых мы указываем для Swagger путь к файлу с XML-комментариями.

Теперь перейдем к какому-нибудь контроллеру API и создадим документацию. Например, откроем файл WeatherForecastController, поставим курсор мыши над методом Get() и трижды нажмем на клавиатуре «/» (слэш). В результате сгенерируется стандартный шаблон описания метода

/// <summary>
/// 
/// </summary>
/// <returns></returns>
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
    return Enumerable.Range(1, 5).Select(index => new WeatherForecast
    {
        Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
        TemperatureC = Random.Shared.Next(-20, 55),
        Summary = Summaries[Random.Shared.Next(Summaries.Length)]
    })
    .ToArray();
}

Добавим описание метода.

/// <summary>
/// Возвращает прогноз погоды на пять дней
/// </summary>
/// <returns>Список обхектов WeatherForecast</returns>
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
    return Enumerable.Range(1, 5).Select(index => new WeatherForecast
    {
        Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
        TemperatureC = Random.Shared.Next(-20, 55),
        Summary = Summaries[Random.Shared.Next(Summaries.Length)]
    })
    .ToArray();
}

Теперь запустим приложение и откроем в браузере Swagger UI

Похожим образом мы можем добавлять описания для параметров методов, если они используются в действии контроллера.

Также при описании Web API важно предоставлять информацию не только о параметрах методов и их назначении, но и о том, какие коды статуса HTTP может возвращать тот или иной метод и что эти коды означают для пользователя. Чтобы добавить описание возвращаемых кодов статуса для метода используется специальный атрибут [ProducesResponseType], а в XML-комментарии <response code=”код_статуса”>, например

/// <summary>
/// Возвращает прогноз погоды на пять дней
/// </summary>
/// <returns>Список обхектов WeatherForecast</returns>
/// <response code="200">Запрос на добавление новой роли успешно выполнен</response>
/// <response code="400">Ошибка выполнения запроса</response>
[HttpGet]
[ProducesResponseType(typeof(IdentityResult), 200, "application/json")]
[ProducesResponseType(typeof(ProblemDetails), 400, "application/json")]
public IEnumerable<WeatherForecast> Get()
{
    return Enumerable.Range(1, 5).Select(index => new WeatherForecast
    {
        Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
        TemperatureC = Random.Shared.Next(-20, 55),
        Summary = Summaries[Random.Shared.Next(Summaries.Length)]
    })
    .ToArray();
}

Здесь мы использовали атрибут ProducesResponseType с тремя параметрами – тип возвращаемого результата, код статуса HTTP, тип данных в теле ответа. Обязательным из этих параметров является только код статуса. Теперь запустим приложение и посмотрим на описание кодов статуса для метода в Swagger UI

Аналогичным образом, используя XML-комментарии, мы можем добавлять описание для свойств моделей, используемых в API, а также использовать аннотации данных для указания обязательных полей (свойств) модели.

Тестирование API в Swagger UI

С помощью Swagger UI мы можем тестировать запросы к API. Для этого необходимо раскрыть вкладку с необходимым методом, например, как показано на рисунке выше, а затем последовательно нажать кнопки «Try It Out» и «Execute». Если же метод API подразумевает отправку каких-либо данных или использование параметров запроса, то их также необходимо предварительно заполнить в соответствующих полях. Ниже представлен результат выполнения метода Get() контроллера WeatherForecastController.

Итого

Для документирования API в ASP.NET Core мы можем использовать инструмент Swagger, который умеет работать с документацией в коде приложения. При необходимости, мы можем настроить Swagger UI для работы с методами, для которых требуется авторизация, например, с использованием JWT-токенов.

Подписаться
Уведомить о
guest
1 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии