最好的總會在不經意間出現。
作為後端程式設計師,免不了與前端同事對接API, 一個書寫良好的API設計文件可有效提高與前端對接的效率。
為避免聯調時來回撕逼,今天我們聊一聊正確使用Swaager的姿勢。
基礎Swagger用法
在ConfigureServices
配置Swagger文件,在Configure
啟用中介軟體
// Install-Package Swashbuckle.AspNetCore 略
services.AddSwaggerGen(
options =>
{
options.SwaggerDoc("v1", new OpenApiInfo { Title = "EAP API", Version = "v1" });
}
);
---
app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "EAP API");
});
應用會在/Swagger
頁面載入最基礎的API文件。
以一個最簡單的Post請求為例,細數這最基礎SwaggerUI的弊病
[HttpPost]
public async Task<bool> AddHotmapAsync([FromBody] CreateHotmapInput createHotmapInput)
{
var model = ObjectMapper.Map<CreateHotmapInput, Hotmap>(createHotmapInput);
model.ProfileId = CurrentUser.TenantId;
return await _hotmaps.InsertAsync(model)!= null;
}
產生如圖示SwaggerUI:
- Post請求的Payload欄位值相對複雜,竟不給前端傳值example?
- 沒有指示前端請求的Content-Type,前端會不會給你另外一個surprise?
- 伺服器沒有指示響應的Content-Type,?
- 伺服器沒有指示響應的預期狀態碼,前端會不會抓狂?
下文就來根治這些頑疾, 書寫一個自述性、優雅的API文件。
Swagger最佳實踐
三下五除二,給出示例:
/// <summary>
/// 新增熱力圖
/// </summary>
/// <remarks>
/// Sample request:
/// ```
/// POST /hotmap
/// {
/// "displayName": "演示名稱1",
/// "matchRule": 0,
/// "matchCondition": "https://www.cnblogs.com/JulianHuang/",
/// "targetUrl": "https://www.cnblogs.com/JulianHuang/",
/// "versions": [
/// {
/// "versionName": "ver2020",
/// "startDate": "2020-12-13T10:03:09",
/// "endDate": "2020-12-13T10:03:09",
/// "offlinePageUrl": "3fa85f64-5717-4562-b3fc-2c963f66afa6", // 沒有繫結圖片和離線網頁的對應屬性傳 null
/// "pictureUrl": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
/// "createDate": "2020-12-13T10:03:09"
/// }
/// ]
/// }
///```
/// </remarks>
/// <param name="createHotmapInput"></param>
/// <returns></returns>
[Consumes("application/json")]
[Produces("text/plan")]
[ProducesResponseType(typeof(Boolean), 200)]
[HttpPost]
public async Task<bool> AddHotmapAsync([FromBody] CreateHotmapInput createHotmapInput)
{
var model = ObjectMapper.Map<CreateHotmapInput, Hotmap>(createHotmapInput);
model.ProfileId = CurrentUser.TenantId;
return await _hotmaps.InsertAsync(model)!=null;
}
- 通過
給API新增XML註釋
注意如果註釋內容包含程式碼,可以使用Markdown的程式碼語法```,在註釋裡面優雅顯示程式碼.
- 通過
Consumes
,Produces
特性指示action接收和返回的資料型別,也就是媒體型別。
Consumes、Produces是指示請求/響應支援的content types的過濾器,位於Microsoft.AspNetCore.Mvc名稱空間下。
- 通過
ProducesResponseType
特性指示伺服器響應的預期內容和狀態碼
API文件結果:
這樣的SwaggerUI才正確表達了後端程式設計師的內心輸出。
在Swagger文件上顯示註釋
- 生成XML註釋文件
在專案上[右鍵]-[屬性]-[生成標籤頁]-[勾選XML文件檔案];
或者直接在專案csproj檔案--[PropertyGroup]新增<GenerateDocumentationFile>true</GenerateDocumentationFile>
- 在
AddSwaggerGen
方法新增下行,啟用註釋檔案
// Set the comments path for the Swagger JSON and UI.
var xmlFile = $"{this.GetType().Assembly.GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
opt.IncludeXmlComments(xmlPath);
這裡囉嗦一下,如果是Abp Vnext解決方案(API是定義在HttpApi專案/Application專案),故我們要為Abp Vnext解決方案載入帶xml註釋的Swagger Json,需要指示xmlFile為HttpApi.xml或者applicaiton.xml
以上就是小碼甲總結的書寫Swagger文件的優雅姿勢:
- 編寫API 傳值example
- 約束請求/響應 支援的媒體型別
- 指示API的預期輸出內容、預期狀態碼
API自述,約束輸入輸出,前端同事再也不會追著你撕逼了!