前一篇簡單介紹如何在一個 ASP.NET Web Api 專案裡安裝 Swashbuckle - Swagger for Web Api 這個套件,基本上都沒有什麼難度,特別要注意的就是 Controller 與 Action 方法與相關類別的 XML 文件註解要記得寫以及維護,在一般的使用情況下的 Api 服務資訊提供已經相當清楚了。
不過提供更加清楚的資訊給使用 Api 服務的開發者對於產品的開發與溝通是有絕對幫助的,但老實說,要把 Swagger 寫得好又要能夠搭配 Web Api 後端程式讓資訊可以自動產生,其實也不是容易的事情,這邊就來說明幾個調整顯示資訊的做法。
ResponseTypeAttribute
MSDN - ResponseTypeAttribute 類別 (System.Web.Http.Description)
使用此項目來指定動作傳回的實體類型 (宣告的傳回類型為 HttpResponseMessage 或 IHttpActionResult)。 ResponseType 會由 ApiExplorer 在產生 ApiDescription 時讀取。
如果你是跟著「ASP.NET Web Api - Help Page」這一篇內容然後建立一個新的 Web Api 專案,然後也是用 Entity Framewok 以及使用 Scaffold 去建立 Controller 類別與內容,那麼可以看看其實在每個 Controller 內幾乎所有 Action 方法上都會有使用「ResponseType」這個 Attribute 吧,
例如以下這個 CustomersController.cs
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Web.Http;
using System.Web.Http.Description;
using HelpPageDemo.Models;
namespace HelpPageDemo.Controllers
{
/// <summary>
/// Customer API 項目.
/// </summary>
public class CustomersController : ApiController
{
private Northwind db = new Northwind();
/// <summary>
/// 取得所有 Customer 資料.
/// </summary>
/// <returns>IQueryable<Customer>.</returns>
public IQueryable<Customer> GetCustomers()
{
return db.Customers;
}
/// <summary>
/// 指定 ID 以取得 Customer 資料.
/// </summary>
/// <param name="id">The identifier.</param>
/// <returns>IHttpActionResult.</returns>
[ResponseType(typeof(Customer))]
public IHttpActionResult GetCustomer(string id)
{
Customer customer = db.Customers.Find(id);
if (customer == null)
{
return NotFound();
}
return Ok(customer);
}
/// <summary>
/// 更新 Customer.
/// </summary>
/// <param name="id">The identifier.</param>
/// <param name="customer">The customer.</param>
/// <returns>IHttpActionResult.</returns>
[ResponseType(typeof(void))]
public IHttpActionResult PutCustomer(string id, Customer customer)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != customer.CustomerID)
{
return BadRequest();
}
db.Entry(customer).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!CustomerExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return StatusCode(HttpStatusCode.NoContent);
}
/// <summary>
/// 新增 Customer.
/// </summary>
/// <param name="customer">The customer.</param>
/// <returns>IHttpActionResult.</returns>
[ResponseType(typeof(Customer))]
public IHttpActionResult PostCustomer(Customer customer)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Customers.Add(customer);
try
{
db.SaveChanges();
}
catch (DbUpdateException)
{
if (CustomerExists(customer.CustomerID))
{
return Conflict();
}
else
{
throw;
}
}
return CreatedAtRoute("DefaultApi", new { id = customer.CustomerID }, customer);
}
/// <summary>
/// 刪除 Customer.
/// </summary>
/// <param name="id">The identifier.</param>
/// <returns>IHttpActionResult.</returns>
[ResponseType(typeof(Customer))]
public IHttpActionResult DeleteCustomer(string id)
{
Customer customer = db.Customers.Find(id);
if (customer == null)
{
return NotFound();
}
db.Customers.Remove(customer);
db.SaveChanges();
return Ok(customer);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
private bool CustomerExists(string id)
{
return db.Customers.Count(e => e.CustomerID == id) > 0;
}
}
}
在 Swagger UI 頁面上的顯示,如下所示:
Model Schema
如果說是 Api 所輸出的資料類別是自己建立的,那麼就需要自己使用 ResponseTypeAttribute 標示在 Action 方法上,如下:
在 Swagger UI 的顯示內容
Model Schema
Model
XML 文件註解 - remarks
https://msdn.microsoft.com/zh-tw/library/3zw4z1ys(v=vs.140).aspx
<remarks> 標記可用於加入型別的相關資訊,補充以 <summary> 指定的資訊。會顯示此資訊。
在 XML 文件註解的 <summary> 標記應用於描述型別或型別成員。而使用 <remarks> 為型別描述加入補充資訊。
直接來看看兩個的不同,
在 Swagger UI 的顯示
上圖「1」所顯示的是 summary 內容,而「2」則是顯示 remarks 的內容,
把每個 Operation 縮合起來,在列表上就會看 summary 的內容來辨識。所以有需要特別對 Api 做補充描述或是比較長的敘述時,就可以寫在 remarks 裡,這樣在 swagger 裡就可以一併輸出顯示。
XML 文件註解 - response
在 Bruce Chen 的「KingKong Bruce記事: ASP.NET Web API 文件產生器(2) - Swagger」這一篇文章裡就有介紹到這一個 XML 文件註解,如果一個 Api 的輸出會有其他自訂的內容時,可以使用 response,
在 Swagger UI 頁面上的輸出如下
一個 Api 的輸出可能因為不同的狀況而輸出不同的內容,所以 response 也可以使用多個,
Response 的 StatusCode 為 2xx,那麼就會將內容顯示在上面的位置,如果是其他的 4xx 或 5xx,則會顯示在下面的位置,
不過這一個做法在「Microsoft Azure 文件 - 自訂 Swashbuckle 產生的 API 定義」這一篇文章裡有特別說到是 Swashbuckle 5.1.5 版之前,這個方法是適用的,那如果是之後的版本呢?
SwaggerResponseAttribute
如果你是現在新安裝 Swashbuckle 的話,那麼可以看看 packages.config 的內容,應該都已經是 5.2.2 之後的版本,
這邊可以使用 SwaggerResponseAttribute 這個類別去替代 XML 文件註解 response ,
修改如下
顯示結果
與之前使用 XML 文件註解 response 不同的是,HttpStatusCode 204 的內容並不會顯示在上面 Response Class 的地方,而是顯示在下方的 Response Messages 的區塊,以 Swagger 來說,HttpStatusCode 為 200 的輸出是正常的執行結果而且是唯一有效的回應。
深入瞭解之後才發覺到 Swagger 及 Swashbuckle - Swagger for Web API 有好多設定,蠻多資訊都還需要在網路上去四處蒐羅,以後如果再有發現到什麼不一樣以及有幫助的的設定,屆時會再分享給大家。
參考連結
KingKong Bruce記事: ASP.NET Web API 文件產生器(2) - Swagger
Microsoft Azure 文件 - 自訂 Swashbuckle 產生的 API 定義
https://github.com/domaindrivendev/Swashbuckle
Swagger and ASP.NET Web API - Part I: Adding Swagger to Web API project
以上
沒有留言:
張貼留言