在前後端分離的開發模式下,文檔就顯得比較重要,哪個介面要傳哪些參數,如果一兩個介面還好,口頭上直接溝通好就可以了,如果介面多了就有點不適用了,沒有介面文檔會大大提高前後端的溝通成本。而 asp.net core 可以通過 [Swashbuckle.AspNetCore](https://github... ...
asp.net core web api 生成 swagger 文檔
Intro
在前後端分離的開發模式下,文檔就顯得比較重要,哪個介面要傳哪些參數,如果一兩個介面還好,口頭上直接溝通好就可以了,如果介面多了就有點不適用了,沒有介面文檔會大大提高前後端的溝通成本。而 asp.net core 可以通過 Swashbuckle.AspNetCore 很方便的集成 swagger 文檔,相比之前 nodejs(express) 和 swagger 集成就很麻煩了,大概這就是強類型語言的優勢吧。C# 是最好的編程語言~~~
集成 swagger
配置 model 以及 api 項目生成 xml 文檔
在對應項目的項目文件中加入下麵的代碼,配置生成 xml 文檔
<PropertyGroup> <GenerateDocumentationFile>true</GenerateDocumentationFile> <NoWarn>$(NoWarn);1591</NoWarn> </PropertyGroup>
在 Web 項目上引用
Swashbuckle.AspNetCore
配置 web 項目使用 swagger
配置 ConfigureServices,配置示例代碼
services.AddSwaggerGen(options => { options.SwaggerDoc(ApplicationHelper.ApplicationName, new Info { Title = "活動室預約系統 API", Version = "1.0" }); options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, $"{typeof(Notice).Assembly.GetName().Name}.xml")); //使用Model項目的xml文檔 options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, $"{typeof(NoticeController).Assembly.GetName().Name}.xml"), true); //使用ApiController項目的xml文檔 });
配置 Configure ,配置示例代碼
app .UseSwagger() .UseSwaggerUI(c => { // c.RoutePrefix = string.Empty; //配置swagger ui首碼,預設值是 "swagger",你可以使用 "string.Empty"來配置首頁就是 swagger ui c.SwaggerEndpoint($"/swagger/{ApplicationHelper.ApplicationName}/swagger.json", "活動室預約系統 API"); c.DocumentTitle = "活動室預約系統 API"; });
現在重新啟動項目,訪問 "/swagger" 就可以看到效果了
其他小技巧
忽略某些api,可以在controller 上加Attribute
[ApiExplorerSettings(IgnoreApi = true)]
,這個Attribute 支持繼承,也就是說你可以在一個BaseController 上加這個 Attribute ,這樣繼承於這個 BaseController 的 Controller 的介面都不會顯示在 swagger 文檔中添加自定義請求頭參數,可以自定義一個 OperationFilter
定義 OperationFilter 示例
public class AuthorizationOperationFilter : IOperationFilter { public void Apply(Operation operation, OperationFilterContext context) { if (operation.Parameters == null) { operation.Parameters = new List<IParameter>(); } var filterPipeline = context.ApiDescription.ActionDescriptor.FilterDescriptors; var isAuthorized = filterPipeline.Any(filter => filter.Filter is AuthorizeFilter); var allowAnonymous = filterPipeline.Any(filter => filter.Filter is IAllowAnonymousFilter); if (isAuthorized && !allowAnonymous) { operation.Parameters.Add(new NonBodyParameter() { Name = "Authorization", In = "header", Type = "string", Description = "access token", Required = true }); } } } public class ApiVersionOperationFilter : IOperationFilter { public void Apply(Operation operation, OperationFilterContext context) { if (operation.Parameters == null) { operation.Parameters = new List<IParameter>(); } context.ApiDescription.TryGetMethodInfo(out var methodInfo); if (methodInfo.DeclaringType.IsDefined(typeof(ApiVersionAttribute), true)) { operation.Parameters.Add(new NonBodyParameter() { Name = "Api-Version", In = "header", Type = "string", Description = "Api-Version", Required = true, Default = "1.0" }); } } }
配置 swagger 使用 OperationFilter
services.AddSwaggerGen(options => { // ... options.OperationFilter<AuthorizationOperationFilter>(); });
更多技術及騷操作參考官方文檔介紹 https://github.com/domaindrivendev/Swashbuckle.AspNetCore
示例
API 介面 swagger 文檔 https://reservation.weihanli.xyz/swagger/index.html
這個API 介面文檔只顯示了API介面,伺服器端其他的Controller 使用了上面提到的 [ApiExplorerSettings(IgnoreApi = true)]
忽略了
最近我的活動室預約的項目增加了一個前後端分離的 angular + marterial 的客戶端,體驗地址 https://reservation-client.weihanli.xyz/
Reference
- https://github.com/domaindrivendev/Swashbuckle.AspNetCore
- https://github.com/WeihanLi/ActivityReservation/tree/dev/ActivityReservation