company_banner

ASP.NET Core: Создание справочных страниц веб-API ASP.NET с помощью Swagger

Автор оригинала: Shayne Boyer
  • Перевод
  • Tutorial
При создании высоконагруженных приложений бывает сложно разобраться в различных API. Сформировать качественную документацию и справочные страницы в рамках веб-API посредством Swagger с интеграцией Swashbuckle .NET Core так же просто, как добавить пару пакетов NuGet и изменить Startup.cs.



Второй цикл статей по ASP.NET Core


1. Создание серверных служб для мобильных приложений.
2. Разработка приложений ASP.NET Core с помощью dotnet watch.
3. Создание справочных страниц веб-API ASP.NET с помощью Swagger.
4. Открытый веб-интерфейс для .NET (OWIN).
5. Выбор правильной среды разработки .NET на сервере.

Введение


Для начала поговорим о терминологии:

  • Swashbuckle — это проект с открытым исходным кодом для создания документов Swagger для веб-API, построенных с помощью ASP.NET Core MVC.
  • Swagger — это машиночитаемое представление RESTful API, которое обеспечивает поддержку интерактивной документации, создание клиентских пакетов SDK и возможности обнаружения.

Данный учебный материал написан по примеру туториала «Создание первого веб-API с помощью ASP.NET Core MVC и Visual Studio». Если вам интересно, его можно скачать с GitHub.

Начало работы


Swashbuckle состоит из двух компонентов:

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

Пакеты NuGet


Чтобы добавить Swashbuckle, можно воспользоваться одним из способов:

  • С помощью консоли диспетчера пакетов:

    Install-Package Swashbuckle -Pre
  • В Visual Studio:

    o Правой кнопкой мыши щелкните проект в Обозревателе решений > Управление пакетами NuGet.
    o Введите в поле поиска текст Swashbuckle.
    o Поставьте флажок Include prerelease (Включить предварительный выпуск).
    o В качестве источника пакетов укажите nuget.org.
    o Коснитесь Swashbuckle package (пакет Swashbuckle), а затем — Install (Установить).

Добавьте Swagger и настройте его в связующее ПО


Добавьте SwaggerGen в набор сервисов в методах Configure и ConfigureServices, активируйте связующее ПО для обработки созданного документа JSON и пользовательского интерфейса Swagger.

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();

    services.AddLogging();

    // Add our repository type
    services.AddSingleton<ITodoRepository, TodoRepository>();

    // Inject an implementation of ISwaggerProvider with defaulted settings applied
    services.AddSwaggerGen();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseMvcWithDefaultRoute();

    // Enable middleware to serve generated Swagger as a JSON endpoint
    app.UseSwagger();

    // Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)
    app.UseSwaggerUi();

}

В Visual Studio нажмите F5 для запуска приложения и перейдите к http://localhost:<random_port>/swagger/v1/swagger.json. Здесь вы увидите созданный документ, описывающий конечные точки.

Примечание: браузеры Microsoft Edge, Google Chrome и Firefox отображают документы JSON без дополнительных настроек. Для Chrome созданы расширения, позволяющие форматировать документ для удобства чтения. Ниже приведен сокращенный пример на JavaScript.

{
   "swagger": "2.0",
   "info": {
       "version": "v1",
       "title": "API V1"
   },
   "basePath": "/",
   "paths": {
       "/api/Todo": {
       "get": {
           "tags": [
           "Todo"
           ],
           "operationId": "ApiTodoGet",
           "consumes": [],
           "produces": [
           "text/plain",
           "application/json",
           "text/json"
           ],
           "responses": {
           "200": {
               "description": "OK",
               "schema": {
               "type": "array",
               "items": {
                   "$ref": "#/definitions/TodoItem"
               }
               }
           }
           },
           "deprecated": false
       },
       "post": {
           ...
       }
       },
       "/api/Todo/{id}": {
       "get": {
           ...
       },
       "put": {
           ...
       },
       "delete": {
           ...
   },
   "definitions": {
       "TodoItem": {
       "type": "object",
       "properties": {
           "key": {
           "type": "string"
           },
           "name": {
           "type": "string"
           },
           "isComplete": {
           "type": "boolean"
           }
       }
       }
   },
   "securityDefinitions": {}
   }

Этот документ используется для работы пользовательского интерфейса Swagger, доступного по адресу: http://localhost:<random_port>/swagger/ui.


Каждый метод в контроллере ToDo можно протестировать из пользовательского интерфейса. Коснитесь метода, чтобы развернуть раздел, добавьте необходимые параметры и нажмите «Try it out!» (Попробовать).



Настройка и расширяемость


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

Информация и описание API


Метод ConfigureSwaggerGen предназначен для добавления сведений об авторе и лицензии, а также описания.

services.ConfigureSwaggerGen(options =>
   {
       options.SingleApiVersion(new Info
       {
           Version = "v1",
           Title = "ToDo API",
           Description = "A simple example ASP.NET Core Web API",
           TermsOfService = "None",
           Contact = new Contact { Name = "Shayne Boyer", Email = "", Url = "http://twitter.com/spboyer"},
           License = new License { Name = "Use under LICX", Url = "http://url.com" }
       });
   });

На следующем рисунке показан пользовательский интерфейс Swagger с информацией о версии.



Комментарии XML


Чтобы включить комментарии XML, правой кнопкой мыши щелкните проект в Visual Studio и выберите Properties (Свойства). Затем поставьте флажок XML Documentation file (Файл документации XML) под разделом Output Settings (Настройки выхода).



Сконфигурируйте Swagger для использования созданного файла XML.

Примечание: для Linux и операционных систем, не принадлежащих к семейству Windows, имена файлов и каталогов чувствительны к регистру. Например, поиск файла с именем ToDoApi.XML возможен в Windows, но невозможен в CentOS.

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();

    services.AddLogging();

    // Add our repository type.
    services.AddSingleton<ITodoRepository, TodoRepository>();

    // Inject an implementation of ISwaggerProvider with defaulted settings applied.
    services.AddSwaggerGen();

    // Add the detail information for the API.
    services.ConfigureSwaggerGen(options =>
    {
        options.SingleApiVersion(new Info
        {
            Version = "v1",
            Title = "ToDo API",
            Description = "A simple example ASP.NET Core Web API",
            TermsOfService = "None",
            Contact = new Contact { Name = "Shayne Boyer", Email = "", Url = "http://twitter.com/spboyer"},
            License = new License { Name = "Use under LICX", Url = "http://url.com" }
        });

        //Determine base path for the application.
        var basePath = PlatformServices.Default.Application.ApplicationBasePath;

        //Set the comments path for the swagger json and ui.
        var xmlPath = Path.Combine(basePath, "TodoApi.xml"); 
        options.IncludeXmlComments(xmlPath);
    });
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseStaticFiles();

    app.UseMvcWithDefaultRoute();

    // Enable middleware to serve generated Swagger as a JSON endpoint.
    app.UseSwagger();

    // Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)
    app.UseSwaggerUi();
    
}

В коде выше ApplicationBasePath получает путь к базовому каталогу приложения, что позволяет настроить полный путь к комментариям XML. TodoApi.xml работает только в этом примере, имя созданного файла XML с комментариями назначается на основе имени приложения.

Если использовать в методе комментарии с тремя косыми чертами, то можно улучшить пользовательский интерфейс Swagger: к заголовку раздела будет добавлено описание.

/// <summary>
/// Deletes a specific TodoItem.
/// </summary>
/// <param name="id"></param>
[HttpDelete("{id}")]
public void Delete(string id)
{
    TodoItems.Remove(id);
}



Помните, что пользовательский интерфейс использует созданный файл JSON, и в нем также содержатся эти комментарии.

"delete": {
  "tags": [
    "Todo"
  ],
  "summary": "Deletes a specific TodoItem",
  "operationId": "ApiTodoByIdDelete",
  "consumes": [],
  "produces": [],
  "parameters": [
    {
      "name": "id",
      "in": "path",
      "description": "",
      "required": true,
      "type": "string"
    }
  ],
  "responses": {
    "204": {
      "description": "No Content"
    }
  },
  "deprecated": false
}

Для большей наглядности добавим <remarks />, содержимое которого может представлять собой текст, объект JSON или XML для дальнейшего документирования метода.

/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <remarks>
/// Note that the key is a GUID and not an integer.
///  
///     POST /Todo
///     {
///        "key": "0e7ad584-7788-4ab1-95a6-ca0a5b444cbb",
///        "name": "Item1",
///        "isComplete": true
///     }
/// 
/// </remarks>
/// <param name="item"></param>
/// <returns>New Created Todo Item</returns>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>
[HttpPost]
[ProducesResponseType(typeof(TodoItem), 201)]
[ProducesResponseType(typeof(TodoItem), 400)]
public IActionResult Create([FromBody, Required] TodoItem item)
{
    if (item == null)
    {
        return BadRequest();
    }
    TodoItems.Add(item);
    return CreatedAtRoute("GetTodo", new { id = item.Key }, item);
}

Обратите внимание, как благодаря дополнительным комментариям улучшился пользовательский интерфейс.



DataAnnotations


В API можно добавить контроллер System.ComponentModel.DataAnnotations, чтобы улучшить элементы пользовательского интерфейса Swagger.

Добавление аннотации [Required] к свойству Name класса TodoItem меняет информацию ModelSchema в пользовательском интерфейсе. Агенты проверки [Produces("application/json")], RegularExpression и другие функции служат для уточнения информации, отображаемой на создаваемой странице. Чем больше метаданных используется в коде, тем более информативной становится справочная страница пользовательского интерфейса или API.

using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace TodoApi.Models
{
    public class TodoItem
    {
        public string Key { get; set; }
        [Required]
        public string Name { get; set; }
        [DefaultValue(false)]
        public bool IsComplete { get; set; }
    }
}

Описание типов ответов


Разработчики, создающие высоконагруженные приложения, уделяют особое внимание выдаваемым результатам, особенно типам ответов, кодам ошибок (если они не стандартные). Для этого используются комментарии XML и DataAnnotations.

Для примера возьмем метод Create(). По умолчанию он выдает ответ «201 Created» (если элемент действительно создан) или «204 No Content» (если в тело POST не переданы данные). Однако не существует документации, которая подскажет, каким будет тот или иной ответ. Чтобы исправить ситуацию, добавим следующий фрагмент кода.

/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <remarks>
/// Note that the key is a GUID and not an integer.
///  
///     POST /Todo
///     {
///        "key": "0e7ad584-7788-4ab1-95a6-ca0a5b444cbb",
///        "name": "Item1",
///        "isComplete": true
///     }
/// 
/// </remarks>
/// <param name="item"></param>
/// <returns>New Created Todo Item</returns>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>
[HttpPost]
[ProducesResponseType(typeof(TodoItem), 201)]
[ProducesResponseType(typeof(TodoItem), 400)]
public IActionResult Create([FromBody, Required] TodoItem item)
{
    if (item == null)
    {
        return BadRequest();
    }
    TodoItems.Add(item);
    return CreatedAtRoute("GetTodo", new { id = item.Key }, item);
}



Настройка пользовательского интерфейса


Готовый пользовательский интерфейс — функциональный и удобный, но при создании страниц документации для API вы наверняка захотите использовать свой бренд или фирменный стиль.

Это можно сделать с помощью компонентов Swashbuckle. Вам нужно будет добавить ресурсы для обслуживания статических файлов, которые обычно не включаются в проект веб-API, а затем создать структуру папок для их размещения.

Добавьте к проекту пакет NuGet «Microsoft.AspNetCore.StaticFiles»: «1.0.0-*».

Включите связующее ПО для статических файлов.

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
   public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
   {
       // Enable static files middleware.
       app.UseStaticFiles();

       app.UseMvcWithDefaultRoute();

       // Enable middleware to serve generated Swagger as a JSON endpoint
       app.UseSwagger();

       // Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)
       app.UseSwaggerUi();
   }

Возьмите файл index.html, который используется на странице пользовательского интерфейса Swagger, из репозитория Github <https://github.com/domaindrivendev/Ahoy/tree/master/test/WebSites/CustomizedUi/wwwroot/swagger/ui>_ и переместите его в папку wwwroot/swagger/ui, после чего создайте новый файл custom.css в той же папке.



Сделайте ссылку на custom.css в файле index.html.

<link href='custom.css' media='screen' rel='stylesheet' type='text/css' />

В следующем CSS представлен образец индивидуально настроенного заголовка страницы.

Файл custom.css
.swagger-section #header
{
    border-bottom: 1px solid #000000;
    font-style: normal;
    font-weight: 400;
    font-family: "Segoe UI Light","Segoe WP Light","Segoe UI","Segoe WP",Tahoma,Arial,sans-serif;
    background-color: black;
}

.swagger-section #header h1
{
    text-align: center;
    font-size: 20px;
    color: white;
}</code>

<i>Тело index.html</i>
<source lang="css"><body class="swagger-section">
   <div id="header">
    <h1>ToDo API Documentation</h1>
   </div>

   <div id="message-bar" class="swagger-ui-wrap" data-sw-translate> </div>
   <div id="swagger-ui-container" class="swagger-ui-wrap"></div>
</body>


Но это далеко не всё, что можно сделать со страницей. Весь перечень возможностей для пользовательского интерфейса смотрите на GitHub в репозитории Swagger UI.
  • +22
  • 18,8k
  • 2
Microsoft
795,00
Microsoft — мировой лидер в области ПО и ИТ-услуг
Поделиться публикацией

Комментарии 2

    0
    dotnet publish при выкладывании xml файла документации игнорирует параметр -o
    В итоге результат компиляции попадает в директорию, заданную параметром, а xml — куда попало.
    Простого решения я не нашёл, пока сняли эту галочку.
      +1
      Отличная статья. Теперь еще добавить создание генерации классов для разных клиентов
      Install swagger-codegen via npm on Windows OS

      Наподобии Add Rest API Client, как аналог Refit

      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

      Самое читаемое