استفاده از XML Comments برای بهبود کیفیت مستندات API
نوشتن توضیحات XML ای برای متدها و پارامترها در پروژههای داتنتی، روشی استاندارد و شناخته شدهاست. برای نمونه در AuthorsController، میخواهیم توضیحاتی را به اکشن متد GetAuthor آن اضافه کنیم:
/// <summary> /// Get an author by his/her id /// </summary> /// <param name="authorId">The id of the author you want to get</param> /// <returns>An ActionResult of type Author</returns> [HttpGet("{authorId}")] public async Task<ActionResult<Author>> GetAuthor(Guid authorId)
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp2.2</TargetFramework> <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel> <GenerateDocumentationFile>true</GenerateDocumentationFile> </PropertyGroup>
اکنون نیاز است وجود این فایل را به تنظیمات SwaggerDoc در کلاس Startup برنامه، اعلام کنیم:
namespace OpenAPISwaggerDoc.Web { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddSwaggerGen(setupAction => { setupAction.SwaggerDoc( // ... ); var xmlCommentsFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlCommentsFullPath = Path.Combine(AppContext.BaseDirectory, xmlCommentsFile); setupAction.IncludeXmlComments(xmlCommentsFullPath); }); }
پس از این تنظیمات اگر برنامه را اجرا کنیم، در Swagger-UI حاصل، این تغییرات قابل مشاهده هستند:
افزودن توضیحات به Response
تا اینجا توضیحات پارامترها و متدها را افزودیم؛ اما response از نوع 200 آن هنوز فاقد توضیحات است:
علت را نیز در تصویر فوق مشاهده میکنید. قسمت responses در OpenAPI specification، اطلاعات خودش را از اسکیمای مدلهای مرتبط دریافت میکند. بنابراین نیاز است کلاس DTO متناظر با Author را به نحو ذیل تکمیل کنیم:
using System; namespace OpenAPISwaggerDoc.Models { /// <summary> /// An author with Id, FirstName and LastName fields /// </summary> public class Author { /// <summary> /// The id of the author /// </summary> public Guid Id { get; set; } /// <summary> /// The first name of the author /// </summary> public string FirstName { get; set; } /// <summary> /// The last name of the author /// </summary> public string LastName { get; set; } } }
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> <GenerateDocumentationFile>true</GenerateDocumentationFile> </PropertyGroup> </Project>
namespace OpenAPISwaggerDoc.Web { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddSwaggerGen(setupAction => { setupAction.SwaggerDoc( // ... ); var xmlFiles = Directory.GetFiles(AppContext.BaseDirectory, "*.xml", SearchOption.TopDirectoryOnly).ToList(); xmlFiles.ForEach(xmlFile => setupAction.IncludeXmlComments(xmlFile)); }); }
در این حالت اگر مجددا برنامه را اجرا کنیم، خروجی ذیل را در قسمت schemas مشاهده خواهیم کرد:
بهبود مستندات به کمک Data Annotations
اگر به اکشن متد UpdateAuthor در کنترلر نویسندگان دقت کنیم، چنین امضایی را دارد:
[HttpPut("{authorId}")] public async Task<ActionResult<Author>> UpdateAuthor(Guid authorId, AuthorForUpdate authorForUpdate)
using System.ComponentModel.DataAnnotations; namespace OpenAPISwaggerDoc.Models { /// <summary> /// An author for update with FirstName and LastName fields /// </summary> public class AuthorForUpdate { /// <summary> /// The first name of the author /// </summary> [Required] [MaxLength(150)] public string FirstName { get; set; } /// <summary> /// The last name of the author /// </summary> [Required] [MaxLength(150)] public string LastName { get; set; } } }
بهبود مستندات متد HttpPatch با ارائهی یک مثال
دو نگارش از اکشن متد UpdateAuthor در این مثال موجود هستند:
یکی HttpPut است
[HttpPut("{authorId}")] public async Task<ActionResult<Author>> UpdateAuthor(Guid authorId, AuthorForUpdate authorForUpdate)
[HttpPatch("{authorId}")] public async Task<ActionResult<Author>> UpdateAuthor( Guid authorId, JsonPatchDocument<AuthorForUpdate> patchDocument)
بهتر است در این حالت مثالی را به استفاده کنندگان از آن ارائه دهیم تا در حین کار با آن، به مشکل برنخورند:
/// <summary> /// Partially update an author /// </summary> /// <param name="authorId">The id of the author you want to get</param> /// <param name="patchDocument">The set of operations to apply to the author</param> /// <returns>An ActionResult of type Author</returns> /// <remarks> /// Sample request (this request updates the author's first name) \ /// PATCH /authors/id \ /// [ \ /// { \ /// "op": "replace", \ /// "path": "/firstname", \ /// "value": "new first name" \ /// } \ /// ] \ /// </remarks> [HttpPatch("{authorId}")] public async Task<ActionResult<Author>> UpdateAuthor( Guid authorId, JsonPatchDocument<AuthorForUpdate> patchDocument)
روش کنترل warningهای کامنتهای تکمیل نشده
با فعالسازی GenerateDocumentationFile در فایل csproj برنامه، کامپایلر، بلافاصله برای تمام متدها و خواص عمومی که دارای کامنت نیستند، یک warning را صادر میکند. یک روش برطرف کردن این مشکل، افزودن کامنت به تمام قسمتهای برنامه است. روش دیگر آن، تکمیل خواص کامپایلر، جهت مواجه شدن با عدم وجود کامنتها در فایل csproj برنامه است:
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp2.2</TargetFramework> <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel> <GenerateDocumentationFile>true</GenerateDocumentationFile> <TreatWarningsAsErrors>false</TreatWarningsAsErrors> <WarningsAsErrors>NU1605;</WarningsAsErrors> <NoWarn>1701;1702;1591</NoWarn> </PropertyGroup>
- اگر میخواهید خودتان را مجبور به کامنت نویسی کنید، میتوانید نبود کامنتها را تبدیل به error کنید. برای این منظور خاصیت TreatWarningsAsErrors را به true تنظیم کنید. در این حالت هر کامنت نوشته نشده، به صورت یک error توسط کامپایلر گوشزد شده و برنامه کامپایل نخواهد شد.
- اگر TreatWarningsAsErrors را خاموش کردید، هنوز هم میتوانید یکسری از warningهای انتخابی را تبدیل به error کنید. برای مثال NU1605 ذکر شدهی در خاصیت WarningsAsErrors، مربوط به package downgrade detection warning است.
- اگر به warning نبود کامنتها دقت کنیم به صورت عبارات warning CS1591: Missing XML comment for publicly visible type or member شروع میشود. یعنی CS1591 مربوط به کامنتهای نوشته نشدهاست. میتوان برای صرفنظر کردن از آن، شمارهی این خطا را بدون CS، توسط خاصیت NoWarn ذکر کرد.
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید: OpenAPISwaggerDoc-03.zip
در قسمت بعد، مشکل خروجی تولید response از نوع 200 را که در قسمت دوم به آن اشاره کردیم، بررسی خواهیم کرد.