使用Swagger為ASP.NET Core WebApi生成API文件
團隊工作中每一個專案都能提供一份詳盡的說明文件的話,自行腦補“這個就叫專業.jpg”。但是利用本來就有限的時間編寫一份讓別人看起來舒服的文件可不是一份美差。故,很多自動化的文件生成器便應運而生,這裡簡單介紹一個很受歡迎的API文件工具Swagger在ASP.NET Core上的應用,其開源在GitHub。
Swagger可以為ASP.NET Core專案生成一份美觀的API文件,並附帶測試功能的UI介面。從實踐出發,接下來介紹如何將Swagger應用在ASP.NET Core WebApi專案中。首先建立ASP.NET Core WebApi的過程這裡就不在贅述了。使用NuGet為專案新增“Swashbuckle.AspNetCore”的引用。本文撰寫時“Swashbuckle.AspNetCore”已經是5.4.1版本了。
來到Startup.cs檔案中的ConfigureServices方法中,向服務容器中註冊Swagger生成器(Swagger generator)從而定義Swagger文件。具體寫法可以參考下面的寫法
1 services.AddSwaggerGen(setup => 2 { 3 setup.SwaggerDoc("DemoApi",//定義文件的名稱 4 new OpenApiInfo 5 { 6 Title = "DemoApi", 7 Version = "v1.0", 8 Contact = newOpenApiContact { Name = "xuhy",Email = "[email protected]" }, 9 Description = "Demo Api 的描述資訊" 10 }); 11 });
這裡定義要生成文件的名稱,及其一些附加的版本資訊,聯絡人資訊和描述資訊等,這些資訊都會在最後創建出的UI介面上有所顯示。
來到Startup.cs檔案中的Configure方法,插入swaggerswagger.ui中介軟體來顯示我們生成的Swagger介面。
1 // 啟用Swagger中介軟體 2 app.UseSwagger();3 // 配置SwaggerUI 4 app.UseSwaggerUI(c => 5 { 6 c.SwaggerEndpoint("/swagger/DemoApi/swagger.json","DemoApi專案文件"); 7 c.RoutePrefix = string.Empty; 8 9 });
到目前為止,最簡單的Swagger配置便已經完成了。值得注意的一點是,我們在開發WebApi專案時,需要顯式的為Action指定Http方法和引數的來源,否則將會都被預設描述成FromQuery。
接下來測試下是否能夠正常顯示,執行專案開啟瀏覽器,如果不出意外便可以看到類似下面的介面。在其中我們可以看到專案中定義的所有Controller和Action。自定義標題及版本資訊也都一一呈現,如下圖。並且在controller的下方,還有一個Schemas模組。在Swashbuckle 的5.0版本後,便可以在Schemas中看到API暴露出來的所有資料型別的具體資訊。
針對Schemas,是基於Newtonsoft 的json序列化器生成的,如果我們ASP.NET Core專案中所用的Json序列化器是預設的System.Text.Json,則就需要為此增加一些配置了。首先利用Nuget新增“Swashbuckle.AspNetCore.Newtonsoft”,並在services.AddSwaggerGen方法之後新增services.AddSwaggerGenNewtonsoftSupport();
在專案的開發過程中,對方法、引數和屬性新增完備的註釋資訊是一個好習慣,Swagger也支援將這些註釋資訊顯示到適當的位置從而更好的起到文件的用途。
首先我們需要對AspNetCore專案進行設定,使其生成XML文件檔案。簡單的設定方法是在專案上右鍵→屬性→生成,將其中的“XML文件檔案”勾選上。但是勾選上之後,專案中所有未進行註釋的方法都會報出警告資訊,有強迫症的同學肯定不能忍。這時只需要在勾選“XML文件檔案”的同時,為“取消顯示警告”中新增“1591”,便可以取消這些警告了。
設定好之後來帶註冊Swagger生成器的AddSwaggerGen方法中,指定的xml檔案的路徑並新增進去即可。
1 //在介面中顯示專案中的註釋 2 var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location); 3 var commentsFileNameMain = typeof(Program).Assembly.GetName().Name + ".XML"; 4 setup.IncludeXmlComments(Path.Combine(basePath,commentsFileNameMain)); 5 setup.DocInclusionPredicate((docName,description) => true);
接下來重新編譯啟動專案,便可以看到專案中的註釋資訊了。
為了達到更多自定義的需求,Swagger為我們提供了3種過濾器(Operation Filter,Schema Filter,Document Filter)來分別過濾不同的部分。舉個例子,有些情況下,Action的方法引數是一個“複雜”型別,但是我們不希望將請求引數中的所有屬性都暴露出來,只想暴露實際需要的屬性到文件中。
首先建立一個自定義的特性,用來標註我們不想在文件中暴露的屬性。
1 [AttributeUsage(AttributeTargets.Property)] 2 public class SwaggerExcludeAttribute : Attribute 3 { 4 }
接下來建立過濾器。
1 public class SwaggerExcludePropFilter : IOperationFilter 2 { 3 public void Apply(OpenApiOperation operation,OperationFilterContext context) 4 { 5 if (context.MethodInfo.DeclaringType == null) return; 6 var parms = context.MethodInfo.GetParameters(); 7 foreach (var parameterInfo in parms) 8 { 9 foreach (var property in parameterInfo.ParameterType.GetProperties()) 10 { 11 var excludeAttributes = property.GetCustomAttribute<SwaggerExcludeAttribute>(); 12 if (excludeAttributes == null) continue; 13 var prop = operation.Parameters.FirstOrDefault(p => p.Name == property.Name); 14 if (prop != null) 15 { 16 operation.Parameters.Remove(prop); 17 } 18 } 19 } 20 } 21 }
注意別忘了在註冊Swagger生成器時將過濾器新增上。
1 //註冊過濾器 2 setup.OperationFilter<SwaggerExcludePropFilter>();
如果此時我們將EmployeeQueryDto的Gender屬性標註上[SwaggerExclude]特性,重新編譯後執行,屬性消失了。
最後,Swagger中還包含更多高階的用法,具體可以參考GitHub。