Swagger UI in AspNetCore WebAPI
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