1. 程式人生 > >Oh my God, Swagger API文件竟然可以這樣寫?

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

最好的總會在不經意間出現。 > 作為後端程式設計師,免不了與前端同事對接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 AddHotmapAsync([FromBody] CreateHotmapInput createHotmapInput) { var model = ObjectMapper.Map(createHotmapInput); model.ProfileId = CurrentUser.TenantId; return await _hotmaps.InsertAsync(model)!= null; } ``` 產生如圖示SwaggerUI: ![](https://img2020.cnblogs.com/blog/587720/202012/587720-20201214104036695-1464905439.png) 1. Post請求的Payload欄位值相對複雜,竟不給前端傳值example? 2. 沒有指示前端請求的Content-Type,前端會不會給你另外一個surprise? 3. 伺服器沒有指示響應的Content-Type,? 4. 伺服器沒有指示響應的預期狀態碼,前端會不會抓狂? ![](https://img2020.cnblogs.com/blog/587720/202012/587720-20201214104020175-828624173.jpg) 下文就來根治這些頑疾, 書寫一個自述性、優雅的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", // 沒有繫結圖片和離線網頁的對應屬性傳 null /// "pictureUrl": "3fa85f64-5717-4562-b3fc-2c963f66afa6", /// "createDate": "2020-12-13T10:03:09" /// } /// ] /// } ///``` ///
/// /// [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; } ``` 1. 通過給API新增XML註釋 > 注意如果註釋內容包含程式碼,可以使用Markdown的程式碼語法```,在註釋裡面優雅顯示程式碼. 2. 通過`Consumes`,`Produces`特性指示action接收和返回的資料型別,也就是媒體型別。 > Consumes、Produces是指示請求/響應支援的content types的過濾器,位於Microsoft.AspNetCore.Mvc名稱空間下。 3. 通過`ProducesResponseType`特性指示伺服器響應的預期內容和狀態碼 API文件結果: ![](https://img2020.cnblogs.com/blog/587720/202012/587720-20201214104111439-1107618601.png) 這樣的SwaggerUI才正確表達了後端程式設計師的內心輸出。 --- ### 在Swagger文件上顯示註釋 1. 生成XML註釋文件 在專案上[右鍵]-[屬性]-[生成標籤頁]-[勾選XML文件檔案]; 或者直接在專案csproj檔案--[PropertyGroup]新增`true
` 2. 在`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自述,約束輸入輸出,前端同事再也不會追著你撕逼了!