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

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

b7803955cc0e4e25981739bf67023d5c.jpg

Второй цикл статей по 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();

    // 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:/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:/swagger/ui.

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

572e8513a6444f4dbc9b6443cd994998.png

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


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 с информацией о версии.

fd629c6b12d14311b37d0b2dfa6da59e.png

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


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

fee83d6970984ab2ad62cb5e647a0ba0.png

Сконфигурируйте 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();

    // 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: к заголовку раздела будет добавлено описание.

/// 
/// Deletes a specific TodoItem.
/// 
/// 
[HttpDelete("{id}")]
public void Delete(string id)
{
    TodoItems.Remove(id);
}

780f084be66a4e97a714a60c3b0d9afc.png

Помните, что пользовательский интерфейс использует созданный файл 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
}

Для большей наглядности добавим , содержимое которого может представлять собой текст, объект JSON или XML для дальнейшего документирования метода.
/// 
/// Creates a TodoItem.
/// 
/// 
/// Note that the key is a GUID and not an integer.
///  
///     POST /Todo
///     {
///        "key": "0e7ad584-7788-4ab1-95a6-ca0a5b444cbb",
///        "name": "Item1",
///        "isComplete": true
///     }
/// 
/// 
/// 
/// New Created Todo Item
/// Returns the newly created item
/// If the item is null
[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);
}

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

9e61d4e6cb524066b0a00599eb1bbbaa.png

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 не переданы данные). Однако не существует документации, которая подскажет, каким будет тот или иной ответ. Чтобы исправить ситуацию, добавим следующий фрагмент кода.

/// 
/// Creates a TodoItem.
/// 
/// 
/// Note that the key is a GUID and not an integer.
///  
///     POST /Todo
///     {
///        "key": "0e7ad584-7788-4ab1-95a6-ca0a5b444cbb",
///        "name": "Item1",
///        "isComplete": true
///     }
/// 
/// 
/// 
/// New Created Todo Item
/// Returns the newly created item
/// If the item is null
[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);
}

a8f861ff05c74f26990f3720d48b4423.png

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


Готовый пользовательский интерфейс — функциональный и удобный, но при создании страниц документации для 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 _ и переместите его в папку wwwroot/swagger/ui, после чего создайте новый файл custom.css в той же папке.

09c6b9b1d1cd4f57b71afb8712b9ccef.png

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

В следующем 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;
}

Тело index.html

   

   
 

333849bf8ce347aa83d3ef425a7a0686.png
Но это далеко не всё, что можно сделать со страницей. Весь перечень возможностей для пользовательского интерфейса смотрите на GitHub в репозитории Swagger UI.

Комментарии (0)

© Habrahabr.ru