Swagger其實包含了三個部分,分別是Swagger Editor文檔接口編輯器,根據接口文檔生成code的Swagger Codegen,以及生成在線文檔的Swagger UI。
在AspNetCore中通常使用Microsoft封裝的Swashbuckle來使用Swagger UI,這是一個AspNetCore的中間件。和其他中間件一樣都是分為register和use兩個部分。Swagger UI主要通過將特殊特性標注過的API信息生成一個OpenAPI的文檔,再將文檔上的信息已網頁的形式顯示給用戶。
Installation
VS中很簡單,直接用NuGet安裝Swashbuckle.AspNetCore即可。
或者使用命令行: dotnet add package --version xxx Swashbuckle.AspNetCore
Register
所有Swagger UI注冊的configue相關的內容都放在AddSwaggerGen這個方法里面:
namespace Microsoft.Extensions.DependencyInjection { public static class SwaggerGenServiceCollectionExtensions { public static IServiceCollection AddSwaggerGen(this IServiceCollection services, Action<SwaggerGenOptions> setupAction = null); public static void ConfigureSwaggerGen(this IServiceCollection services, Action<SwaggerGenOptions> setupAction); } }
AddSwaggerGen這個方法主要用戶注冊中間件的時候添加一些參數,其中重要的有:
SwaggerDoc
添加一個swagger document,主要用戶存儲生成出來的OpenAPI文檔。以及一些文檔基本信息,如:作者、描述、license等。
XXXFilter
自定義filter,XXX為Swagger中的對象,當XXX創建完成后,filter可以定義操作對XXX進行處理。
AddSecurityDefinition和AddSecurityRequirement
用於給Swagger添加驗證的部分。
IncludeXmlComments
為OpenAPI提供注釋內容的xml,需要在IDE里面配置生成對應的XML文件。(當vs中使用生成xml文檔文件這個功能的時候,如果有方法沒有添加注釋,vs會有提示,如果要避免這個提示,可以在下圖中的Suppress warnings中把1591禁掉。)
MapType
很多時候,json的類型會有自定義的轉化,這個時候需要使用MapType來讓Swagger知道這個轉化。
舉一個PhoneNumber的例子:
public class PhoneNumber { public string CountryCode { get; set; } public string AreaCode { get; set; } public string SubscriberId { get; set; } }
[HttpGet("PhoneNumber")] public PhoneNumber GetPhoneNumber() { return new PhoneNumber() { AreaCode = "123", CountryCode = "456", SubscriberId = "789" }; }
如果在AddSwaggerGen中使用了
c.MapType<PhoneNumber>(() => new Schema { Type = "string" });
生成的json的response中就從PhoneNumber類變成了string。
"/market/PhoneNumber": { "get": { "tags": [ "Market" ], "operationId": "GetPhoneNumber", "consumes": [], "produces": [ "text/plain", "application/json", "text/json" ], "parameters": [], "responses": { "200": { "description": "Success", "schema": { "type": "string" } } } } }
如果去掉,是這樣的。
"/market/PhoneNumber": { "get": { "tags": [ "Market" ], "operationId": "GetPhoneNumber", "consumes": [], "produces": [ "text/plain", "application/json", "text/json" ], "parameters": [], "responses": { "200": { "description": "Success", "schema": { "$ref": "#/definitions/PhoneNumber" } } } } }
Use
RouteTemplate
UseSwagger中配置Swagger頁面路由信息。默認情況下是swagger/{documentName}/swagger.json
RoutePrefix
類似SharePoint中的host name,默認為swagger,如果不需要可以設置為“”。
SwaggerEndpoint
OpenAPI文件的訪問URL,這個url和RouteTemplate以及SwaggerDoc的name一定要一致,不然就會有page not found的錯。從瀏覽器訪問json文件的時候url中的document name是區分大小寫的。
當請求OpenAPI文件的時候,會從SwaggerEndpoint配置的url中配合RouteTemplate一起解析document的name。
下面是RouteTemplate的配置:
1 app.UseSwagger(option => 2 { 3 option.RouteTemplate = string.Format("{0}/{1}", prefix, "{documentName}/swagger.json"); 4 });
解析document name的過程。
1 private bool RequestingSwaggerDocument(HttpRequest request, out string documentName) 2 { 3 documentName = null; 4 if (request.Method != "GET") return false; 5 6 var routeValues = new RouteValueDictionary(); 7 if (!_requestMatcher.TryMatch(request.Path, routeValues) || !routeValues.ContainsKey("documentName")) return false; 8 9 documentName = routeValues["documentName"].ToString(); 10 return true; 11 }
API decorate
ApiExploreri通過AspNetCore的MVC中的routing特性標簽來識別api的。
[HttpPost] public void CreateProduct(Product product) ...
[HttpGet] public IEnumerable<Product> SearchProducts(string keywords) ...
具體使用方式請參考Routing to controller actions in ASP.NET Core
Reference
Swashbuckle official documentation:https://github.com/domaindrivendev/Swashbuckle.AspNetCore
AspNetCore MVC Routing:https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-3.0