Oh my God, Swagger API文檔竟然可以這樣寫?


“作為后端程序員,免不了與前端同事對接API, 一個書寫良好的API設(shè)計文檔可有效提高與前端對接的效率。
為避免聯(lián)調(diào)時來回撕逼,今天我們聊一聊正確編寫Swaager API文檔的姿勢。
基礎(chǔ)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");
});
應(yīng)用會在/Swagger頁面加載最基礎(chǔ)的API文檔。
以一個最簡單的Post請求為例,細(xì)數(shù)這最基礎(chǔ)Swagger文檔的弊病:
[HttpPost]
public?async?Task?AddHotmapAsync([FromBody]?CreateHotmapInput?createHotmapInput)
{
?????var?model?=?ObjectMapper.Map(createHotmapInput);
?????model.ProfileId?=?CurrentUser.TenantId;
?????return?await?_hotmaps.InsertAsync(model)!=?null;
}
產(chǎn)生如圖示SwaggerUI:
Post請求的Payload字段過于復(fù)雜,竟不給前端傳值example? 沒有約定請求的媒體類型,前端會不會給你另外一個surprise? API 文檔沒有指示響應(yīng)的媒體類型,前端以哪種姿勢接收? API文檔沒有指示響應(yīng)的預(yù)期輸出內(nèi)容、狀態(tài)碼,前端會不會抓狂?

下文就來根治這些頑疾, 書寫一個自述性、優(yōu)雅的API文檔。
Swagger最佳實踐
三下五除二,給出示例:
///?
///?添加熱力圖
///?
///?
///?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",??//??沒有綁定圖片和離線網(wǎng)頁的對應(yīng)屬性傳?null
///??????????"pictureUrl":?"3fa85f64-5717-4562-b3fc-2c963f66afa6",
///??????????"createDate":?"2020-12-13T10:03:09"
///??????}
///????]
///??}
///```
///?
///?"createHotmapInput">
///?
[Consumes("application/json")]
[Produces("text/plan")]
[ProducesResponseType(typeof(Boolean),?200)]
[HttpPost]
public?async?Task?AddHotmapAsync([FromBody]?CreateHotmapInput?createHotmapInput)
{
?????var?model?=?ObjectMapper.Map(createHotmapInput);
??? ?model.ProfileId?=?CurrentUser.TenantId;
?????return?await?_hotmaps.InsertAsync(model)!=null;
}
通過 給API添加XML注釋: remarks
“注意如果注釋內(nèi)容包含代碼,可以使用Markdown的代碼語法```,在注釋里面優(yōu)雅顯示代碼。
通過 Consumes,Produces特性指示action接收和返回的數(shù)據(jù)類型,也就是媒體類型。
“Consumes、Produces是指示請求/響應(yīng)支持的content-type的過濾器,位于Microsoft.AspNetCore.Mvc命名空間下。
通過 ProducesResponseType特性指示API響應(yīng)的預(yù)期內(nèi)容、狀態(tài)碼
API文檔顯示如下:

這樣的Swagger文檔才正確表達(dá)了后端程序員的內(nèi)心輸出。
在Swagger文檔上顯示注釋
生成XML文檔文件 在項目上[右鍵]-[屬性]-[生成標(biāo)簽頁]-[勾選XML文檔文件]; 或者直接在項目csproj文件--[PropertyGroup]添加 true 在 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。

以上就是小碼甲總結(jié)的書寫Swagger文檔的優(yōu)雅姿勢:?
編寫API 傳值example
約束請求/響應(yīng) 支持的媒體類型
指示API的預(yù)期輸出內(nèi)容、預(yù)期狀態(tài)碼
內(nèi)容自述,格式工整,前端同事再也不會追著你撕逼了!
