(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

WebAPI: автогенерация веб-документации REST API

Владимир Юнев

В этой записи блога мы близко рассмотрим ApiExplorer, являющийся реализацией IApiExplorer по умолчанию и увидим как с помощью него можно быстро сгенерировать веб-документацию по доступному REST API. В этой документации будет содержаться разнообразная информация, например, правильные URL, допустимые HTTP-методы, ожидаемые для запросов параметры. Такого рода информация для вашего REST-сервиса позволит сторонним разработчикам, потребляющим ваш API, точно знать как правильно вызывать его части. Наверное, самое приятное в такой странице веб-документации состоит в том, что она будет обновляться автоматически вместе с обновлением вашего REST API.

ApiExplorer

Основной целью этого класса является генерирование коллекции элементов ApiDescription. Это производится с помощью статической проверки маршрутов и доступных действий внутри ваших контроллеров. Каждый элемент ApiDescription описывает API доступный через ваш сервис. Как вы можете видеть на упрощенной диаграмме (рисунок 1) ApiDescription содержит базовую информацию такую как, HttpMethod, RelativePath, Documentation и т.д. Но кроме того, он содержит элемент ApiDescriptor, который является частью ядра WebAPI знающей все о соответствующем действии. Вы можете использовать этот элемент для получения доступа к обширной информации, такой как имя действия, возвращаемый тип, пользовательские атрибуты и т.д. Точно так же вы можете использовать элемент ParameterDescriptor для изучения ожидаемых параметров данного API.

Рис.1. Диаграмма класса ApiDescription

Давайте посмотрим, как мы можем сгенерировать страницу помощи.

Генерация страницы помощи по API

Для простоты я буду считать, что мы используем наш REST-сервис вместе с ASP.NET MVC. Другие идеи по реализации вы можете посмотреть ниже в разделе "Другие реализации".

Пример

Для примера я использую стандартный шаблон "Web API".

Рис.2. Выбор проекта Web API

По умолчанию это шаблон содержит MVC-контроллер HomeController и Web API ValuesController. Давайте поменяем действие Index в HomeController для того, чтобы отобразить нашу страницу помощи.

Шаг 1. Используем ApiExplorer в представлении

Добавим следующие две строки кода в действие Index:

  1. public ActionResult Index()
  2. {
  3.     var apiExplorer = GlobalConfiguration.Configuration.Services.GetApiExplorer();
  4.     return View(apiExplorer);
  5. }

Шаг 2. Настроим представление для отображения API

В Index.cshtml мы можем указать типом модели IApiExplorer:

@model System.Web.Http.Description.IApiExplorer

Затем мы можем пройтись по всем элементам Model.ApiDescriptions для отображения поддерживаемых HTTP-методов, относительных URL, описания действий и ожидаемых параметров.

  1. @foreach (var api in Model.ApiDescriptions)
  2. {
  3.     <li>
  4.     <h5>@api.HttpMethod @api.RelativePath</h5>
  5.     <blockquote>
  6.     <p>@api.Documentation</p>
  7.     @if (api.ParameterDescriptions.Count > 0)
  8.     {
  9.         <h6>Parameters</h6>
  10.         <ul>
  11.         @foreach (var parameter in api.ParameterDescriptions)
  12.         {
  13.             <li>@parameter.Name: @parameter.Documentation (@parameter.Source)</li>
  14.         }
  15.         </ul>
  16.     }
  17.     </blockquote>
  18.     </li>
  19. }

Конечно вы можете настроить свою HTML-разметку так как вам захочется. Ниже полный код для представления:

  1. @model System.Web.Http.Description.IApiExplorer 
  2. <div id="body">
  3.     <section class="featured">
  4.         <div class="content-wrapper">
  5.             <hgroup class="title">
  6.                 <h1>ASP.NET Web API Help Page</h1>
  7.             </hgroup>
  8.         </div>
  9.     </section>
  10.     <section class="content-wrapper main-content clear-fix">
  11.         <h3>APIs</h3>
  12.         <ul>
  13.         @foreach (var api in Model.ApiDescriptions) 
  14.         { 
  15.             <li>
  16.             <h5>@api.HttpMethod @api.RelativePath</h5>
  17.             <blockquote>
  18.             <p>@api.Documentation</p>
  19.             @if (api.ParameterDescriptions.Count > 0) 
  20.             { 
  21.                 <h6>Parameters</h6>
  22.                 <ul>
  23.                 @foreach (var parameter in api.ParameterDescriptions) 
  24.                 { 
  25.                     <li>@parameter.Name: @parameter.Documentation (@parameter.Source)</li>
  26.                 } 
  27.                 </ul>
  28.             } 
  29.             </blockquote>
  30.             </li>
  31.         } 
  32.         </ul>
  33.     </section>
  34. </div>

Теперь, после запуска приложения вы должны увидеть следующую страницу с описанием доступного REST API (рисунок 3).

Рис.3. Страница с веб-документацией

Если вы взгляните внимательнее, описание API просто говорит "Documentation for XYZ", что естественно не очень полезно. Давайте добавим немного полезной информации.

Шаг 3. Добавление документации

Во время генерации документации для API наш ApiExplorer запрашивает IDocumentationProvider для предоставления необходимой информации. IDocumentationProvider - это абстрактный механизм, который позволяет вам определять собственный способ получения информации для документирования действий API. Это позволяет вам реализовать собственный IDocumentationProvider, который будет извлекать информацию из нужного вам источника. Ниже вы можете найти пример реализации IDocumentationProvider, которая извлекает информацию из документирующих комментариев C#.

  1. public class XmlCommentDocumentationProvider : IDocumentationProvider 
  2. {
  3.     XPathNavigator _documentNavigator;
  4.     private const string _methodExpression = "/doc/members/member[@name='M:{0}']";
  5.     private static Regex nullableTypeNameRegex = new Regex(@"(.*\.Nullable)" + Regex.Escape("`1[[") + "([^,]*),.*");
  6.  
  7.     public XmlCommentDocumentationProvider(string documentPath)
  8.     {
  9.         XPathDocument xpath = new XPathDocument(documentPath);
  10.         _documentNavigator = xpath.CreateNavigator();
  11.     }
  12.  
  13.     public virtual string GetDocumentation(HttpParameterDescriptor parameterDescriptor)
  14.     {
  15.         ReflectedHttpParameterDescriptor reflectedParameterDescriptor = parameterDescriptor as ReflectedHttpParameterDescriptor;
  16.         if (reflectedParameterDescriptor != null)
  17.         {
  18.             XPathNavigator memberNode = GetMemberNode(reflectedParameterDescriptor.ActionDescriptor);
  19.             if (memberNode != null)
  20.             {
  21.                 string parameterName = reflectedParameterDescriptor.ParameterInfo.Name;
  22.                 XPathNavigator parameterNode = memberNode.SelectSingleNode(string.Format("param[@name='{0}']", parameterName));
  23.                 if (parameterNode != null)
  24.                 {
  25.                     return parameterNode.Value.Trim();
  26.                 }
  27.             }
  28.         }
  29.  
  30.         return "No Documentation Found.";
  31.     }
  32.  
  33.     public virtual string GetDocumentation(HttpActionDescriptor actionDescriptor)
  34.     {
  35.         XPathNavigator memberNode = GetMemberNode(actionDescriptor);
  36.         if (memberNode != null)
  37.         {
  38.             XPathNavigator summaryNode = memberNode.SelectSingleNode("summary");
  39.             if (summaryNode != null)
  40.             {
  41.                 return summaryNode.Value.Trim();
  42.             }
  43.         }
  44.  
  45.         return "No Documentation Found.";
  46.     }
  47.  
  48.     private XPathNavigator GetMemberNode(HttpActionDescriptor actionDescriptor)
  49.     {
  50.         ReflectedHttpActionDescriptor reflectedActionDescriptor = actionDescriptor as ReflectedHttpActionDescriptor;
  51.         if (reflectedActionDescriptor != null)
  52.         {
  53.             string selectExpression = string.Format(_methodExpression, GetMemberName(reflectedActionDescriptor.MethodInfo));
  54.             XPathNavigator node = _documentNavigator.SelectSingleNode(selectExpression);
  55.             if (node != null)
  56.             {
  57.                 return node;
  58.             }
  59.         }
  60.  
  61.         return null;
  62.     }
  63.  
  64.     private static string GetMemberName(MethodInfo method)
  65.     {
  66.         string name = string.Format("{0}.{1}", method.DeclaringType.FullName, method.Name);
  67.         var parameters = method.GetParameters();
  68.         if (parameters.Length != 0)
  69.         {
  70.             string[] parameterTypeNames = parameters.Select(param => ProcessTypeName(param.ParameterType.FullName)).ToArray();
  71.             name += string.Format("({0})", string.Join(",", parameterTypeNames));
  72.         }
  73.  
  74.         return name;
  75.     }
  76.  
  77.     private static string ProcessTypeName(string typeName)
  78.     {
  79.         //handle nullable
  80.         var result = nullableTypeNameRegex.Match(typeName);
  81.         if (result.Success)
  82.         {
  83.             return string.Format("{0}{{{1}}}", result.Groups[1].Value, result.Groups[2].Value);
  84.         }
  85.         return typeName;
  86.     }
  87. }

После этого вам необходимо подключить ваш собственный IDocumentationProvider. Простейшим способом это сделать является конфигурирование через HttpConfiguration. Обратите внимание, что XmlCommentDocumentationProvider должен знать где находится файл XML с комментариями.

  1. var config = GlobalConfiguration.Configuration;
  2. config.Services.Replace(typeof(IDocumentationProvider), 
  3.     new XmlCommentDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/MyApp.xml")));

Вы можете убедиться в том, что генерация вашего файла XML документации включена в настройках проекта (рисунок 4).

Рис.4. Установка параметра генерации файла документации

После этого убедитесь, что ваш код содержит комментарии документирования:

В заключении, запустите ваш проект снова и убедитесь, что документация из вашего кода теперь доступна на странице веб-документации вашего REST API (рисунок 5).

Рис.5. Страница веб-документации с описанием методов

Исключение контроллера/действия из документации

По некоторым причинам может понадобиться исключить контроллер или действие из генерации документации API. Для этого вы можете воспользоваться специальным атрибутом ApiExplorerSettingsAttribute:

  1. public class ValuesController : ApiController 
  2. {
  3.     [ApiExplorerSettings(IgnoreApi = true)]
  4.     public void MySpecialAction()
  5.     {
  6.     }
  7. }

Он может применяться и для контроллера:

  1. [ApiExplorerSettings(IgnoreApi = true)]
  2. public class MySpecialController : ApiController 
  3. {

Другие реализации

То что я показал выше - это всего лишь один путь для реализации страницы веб-документации. Но могут быть и многие другие пути, вот, для примера, другая идея:

  • Создайте свою реализацию ApiController (например HelpController). Внутри контроллера у вас будет действие GET, которое возвращает информацию об API (в каком угодно формате). Внутри же HelpController будет использовать ApiExplorer и всю доступную через него информацию. Преимущество этого подхода в том, что он будет работать как в self-hosted режиме, так и в виде веб-сервиса.

Замечание переводчика

В статье описан будущий функционал, который будет добавлен в ASP.NET WebAPI. Вы можете попробовать его уже сегодня, установив необходимые пакеты из репозитория WebAPI aspnetwebstack.codeplex.com/.../353867 подробнее о том, как это можно сделать написано в отдельной статье.

Автор статьи: Владимир Юнев.

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 08.06.2012 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Stimulsoft Reports Server Team 10 users
Microsoft Office для дома и учебы 2019 (лицензия ESD)
IBM RATIONAL Clearcase Floating User License + Sw Subscription & Support 12 Months
ABBYY Lingvo x6 Европейская Домашняя версия, электронный ключ
GFI LanGuard подписка на 1 год (25-49 лицензий)
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
СУБД Oracle "с нуля"
OS Linux для начинающих. Новости + статьи + обзоры + ссылки
Новые материалы
Мастерская программиста
Утиль - лучший бесплатный софт для Windows
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100