这算是在博客园的第一篇博客吧,以后发的应该也会同步到博客园上。前端
此前的博客地址: https://blog.mytyiluo.cnnode
Swagger是一个开源软件框架,可帮助开发人员设计,构建,记录和使用RESTful Web服务。ios
其中,Swagger能够生成一个交互式的API控制台,以便于快速测试API。git
从我的角度讲,Swagger对于先后端分离的小团队来讲是很是有帮助的。尤为是像咱们这种平时没写文档习惯的人来讲,Swagger能根据代码自动生成文档可谓是一大福音,不再用被人追着问这API究竟是怎么用的。github
这里,我将会具体说下最近我使用Swagger的一些心得和体会,团队的开发环境以下:json
对于ASP.NET Core来讲,生成文档这一步仍是相对容易的,且对代码基本没有侵入性。只需在Startup中配置一下便可,大体步骤基本以下:axios
这里,我所使用的是Swashbuckle.AspNetCore,直接用VS的NuGet包管理器下载便可。小程序
而后在ConfigureServices
中配置以下:后端
services.AddSwaggerGen(c => { // 定义文档 c.SwaggerDoc("v1", new Info { Title = "Qincai API", Version = "v1" }); });
并在Configure
中启用该Services:微信小程序
// 使用Swagger app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "Qincai API v1"); });
随后运行,打开浏览器host/swagger
便可看到所生成的API文档。
若还有不清楚的,能够参考微软官方的文档。
完成到这里,是否是发现你和图中生成的样子有点不太同样,好比说,为何没有注释,以及认证用的小锁,那这里咱们就须要进一步配置。
若是你们有在VS中写C#经历的话,确定会对XML注释影响深入,经过简单的///
就能够自动生成规范的注释格式。那这里,咱们的Swagger也正是利用了这些XML注释来标记对应的API。
首先,咱们须要启用VS中导出XML文档的功能,在项目属性中,生成 > 输出,勾选XML文档文件,并填写对应的路径,我所写的是项目根目录。
而后再到以前的ConfigureServices
中添加以下:
services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Title = "Qincai API", Version = "v1" }); // file 是你在项目属性中配置的相对路径 var filePath = System.IO.Path.Combine(AppContext.BaseDirectory, file); c.IncludeXmlComments(filePath); });
从新生成,再运行,你能够看到Swagger中就对API以及参数添加上了注释。
在实际开发中,咱们经常是须要给咱们的API添加上认证功能以免非法的访问,所以咱们也就须要给Swagger中的API标识上是否须要认证,而且添加提供Token的功能,以方便在Swagger的控制台中调试。
简单来讲,仍是在ConfigureServies
中,配置以下:
services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Title = "Qincai API", Version = "v1" }); var filePath = System.IO.Path.Combine(AppContext.BaseDirectory, file); c.IncludeXmlComments(filePath); // 定义认证方式 c.AddSecurityDefinition("Bearer", new ApiKeyScheme { In = "header", Description = "请键入JWT Token,格式为'Bearer '+你的Token。", Name = "Authorization", Type = "apiKey" }); // 网上为全局API添加认证参数的方法 // c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>> { // { "Bearer", Enumerable.Empty<string>() }, // }); // 在过滤器中为须要认证的API添加对应参数 // 过滤器的定义见下文 c.OperationFilter<AuthorizationHeaderOperationFilter>(); });
这里值得说一下的是,网上广泛都是全局添加认证参数,致使一些不须要认证的API也被打上了标识,这在Swagger 控制台中影响倒不大,但在后续的导出API时就麻烦了,全部在这里,我使用自定义过滤器的方式来只为须要认证的API添加认证参数。
根据上文,咱们先定义一个AuthorizationHeaderOperationFilter
类,它须要实现IOperationFilter
接口,类定义以下:
/// <summary> /// 判断是否须要添加Authorize Header /// </summary> public class AuthorizationHeaderOperationFilter : IOperationFilter { /// <summary> /// 为须要认证的Operation添加认证参数 /// </summary> /// <param name="operation">The Swashbuckle operation.</param> /// <param name="context">The Swashbuckle operation filter context.</param> public void Apply(Operation operation, OperationFilterContext context) { // 获取对应方法的过滤器描述 // 应该也就是所添加的Attribute var filterPipeline = context.ApiDescription.ActionDescriptor.FilterDescriptors; // 判断是否添加了AuthorizeFilter // 也就是[Authorize] var isAuthorized = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is AuthorizeFilter); // 判断是否添加了IAllowAnonymousFilter // 也就是[AllowAnonymous] var allowAnonymous = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is IAllowAnonymousFilter); // 仅当须要认证且不是AllowAnonymous的状况下,添加认证参数 if (isAuthorized && !allowAnonymous) { // 若该Operation不存在认证参数的话, // 这个Security将是null,而不是空的List if (operation.Security == null) operation.Security = new List<IDictionary<string, IEnumerable<string>>>(); // 添加认证参数 operation.Security.Add(new Dictionary<string, IEnumerable<string>> { { "Bearer", new string[] { } } }); } } }
从新生成后运行,应该就能够看到须要认证的API都带上了一把小锁。
虽然说配置并不算难,但仍是须要注意一些地方。
注意写好XML注释
以前也说了,Swagger的注释是根据XML文档生成的,反过来讲,若是你没写XML注释,Swagger上也就是不会有注释的。
另外,在你启用XML文档输出以后,VS也会很贴心的为你把没有写XML注释的地方都标为Warning。╮(╯▽╰)╭,因此安心的把注释都补一遍吧。
为参数添加数据注解
Swagger是支持部分数据注解的,好比[Required]
之类的。
结合[ApiController]
自带的模型验证功能,岂不美哉。
将XML文档复制到输出目录
若你在发布应用后发现XML不见了,那可能就是你没有为XML文档文件配置复制到输出目录的属性。
打开资源管理器,右键对应的文件,咱们在属性中能够看到有复制到输出目录的属性,将其设置为始终复制就Ok。
以上就是我最近所用到的Swagger的一些功能。
在一开始也说了,使用Swagger的主要目的就是方便小团队的沟通,但事实上,由于咱们前端的人少(你们都是CSS鬼才),致使咱们开发新API的速度每每比前端进度快,没几天前端那边就须要更新一下API的库(将小程序的CallBack封装成Promise)。
所以,就有了根据Swagger自动生成Js可用的API文件的想法,其实想法的自己是来自于Abp项目的设计(真的很优秀),但出于一些方面的考虑,咱们姑且还没采用Abp。
随后,就是查找资料了,确实Swagger有这方面的支持,其中官方关于Js的库是彻底动态的,但惋惜不适用于小程序。而后,就发现了第三方的swagger-js-codegen,可用于生成静态的Js代码,且提供了自定义模板的功能。网上也很多基于这个库的其余模板,好比说axios
之类的,但没有适用于微信小程序的,不过问题不大,模板是基于mustache
的,动手撸就是了。
模板代码有点长就不在这里放出了,你们还请移步GitHub。
这里我就简单说下大体思路,
模板自己是基于原来的nodejs模板改的,咱们所需作的就是将http请求部分的代码改成使用wx.request
,以下简单的封装便可:
/** * HTTP Request * @method * @name {{&className}}#request * @param {string} method - HTTP 请求方法 * @param {string} url - 开发者服务器接口地址 * @param {object} data - 请求的参数 * @param {object} headers - 设置请求的 header ,默认为 application/json */ request(method, url, parameters, data, headers){ return new Promise((resolve, reject) => { wx.request({ url: url, data: data, header: headers, method: method, success: res => { if(res.statusCode >= 200 && res.statusCode <= 299) { resolve(res.data) } else { reject(res) } }, fail: e => reject(e) }) }) }
对应method的话,基本没怎么改,只根据微信小程序全部参数都是传递给data,作了点简化。
对于认证部分,根据咱们本身的需求,换成了这样的实现:
new Promise((resolve, reject) => { this.authenticate() .then(token => { headers['Authorization'] = 'Bearer ' + token; resolve(this.request('{{method}}', domain + path, parameters, data, headers)) }) })
其中this.authenticate
是由外部传入的function
,返回一个包含Token
的Promise
。
导出后,在小程序中的使用就相似于:
import API from './api.js' api = new API('http://localhost:5000') api.setAuthenticate(function () { return new Promise((resolve, reject) => { // 你的认证逻辑 resolve(token) }) })
而后,就能够开心地调用各类方法了。
最后,再放一遍Demo的连接:https://github.com/yiluomyt/swagger-wxopen-codegen-template,发现有问题欢迎提Issue。