Swagger 导出API

这算是在博客园的第一篇博客吧,之后发的应该也会同步到博客园上。

此前的博客地址: https://blog.mytyiluo.cn

Swagger简介

Swagger是一个开源软件框架,可帮助开发人员设计,构建,记录和使用RESTful Web服务。

其中,Swagger可以生成一个交互式的API控制台,以便于快速测试API。

从个人角度讲,Swagger对于前后端分离的小团队来说是非常有帮助的。尤其是像我们这种平时没写文档习惯的人来说,Swagger能根据代码自动生成文档可谓是一大福音,再也不用被人追着问这API到底是怎么用的。

这里,我将会具体说下最近我使用Swagger的一些心得和体会,团队的开发环境如下:

  • ASP.NET Core 2.1 (Visual Studio 2017 Community)
  • 微信小程序 (官方工具+Visual Studio Code)

生成Swagger API 文档

对于ASP.NET Core来说,生成文档这一步还是相对容易的,且对代码基本没有侵入性。只需在Startup中配置一下即可,大致步骤基本如下:

添加NuGet包

这里,我所使用的是Swashbuckle.AspNetCore,直接用VS的NuGet包管理器下载即可。

然后在ConfigureServices中配置如下:

  1. services.AddSwaggerGen(c =>
  2. {
  3. // 定义文档
  4. c.SwaggerDoc("v1", new Info { Title = "Qincai API", Version = "v1" });
  5. });

并在Configure中启用该Services:

  1. // 使用Swagger
  2. app.UseSwagger();
  3. app.UseSwaggerUI(c =>
  4. {
  5. c.SwaggerEndpoint("/swagger/v1/swagger.json", "Qincai API v1");
  6. });

随后运行,打开浏览器host/swagger即可看到所生成的API文档。

若还有不清楚的,可以参考微软官方的文档

完成到这里,是不是发现你和图中生成的样子有点不太一样,比如说,为什么没有注释,以及认证用的小锁,那这里我们就需要进一步配置。

添加XML注释

如果大家有在VS中写C#经历的话,肯定会对XML注释影响深刻,通过简单的///就可以自动生成规范的注释格式。那这里,我们的Swagger也正是利用了这些XML注释来标记对应的API。

首先,我们需要启用VS中导出XML文档的功能,在项目属性中,生成 > 输出,勾选XML文档文件,并填写对应的路径,我所写的是项目根目录。

然后再到之前的ConfigureServices中添加如下:

  1. services.AddSwaggerGen(c =>
  2. {
  3. c.SwaggerDoc("v1", new Info { Title = "Qincai API", Version = "v1" });
  4. // file 是你在项目属性中配置的相对路径
  5. var filePath = System.IO.Path.Combine(AppContext.BaseDirectory, file);
  6. c.IncludeXmlComments(filePath);
  7. });

重新生成,再运行,你可以看到Swagger中就对API以及参数添加上了注释。

添加认证功能

在实际开发中,我们常常是需要给我们的API添加上认证功能以避免非法的访问,因此我们也就需要给Swagger中的API标识上是否需要认证,并且添加提供Token的功能,以方便在Swagger的控制台中调试。

简单来说,还是在ConfigureServies中,配置如下:

  1. services.AddSwaggerGen(c =>
  2. {
  3. c.SwaggerDoc("v1", new Info { Title = "Qincai API", Version = "v1" });
  4. var filePath = System.IO.Path.Combine(AppContext.BaseDirectory, file);
  5. c.IncludeXmlComments(filePath);
  6. // 定义认证方式
  7. c.AddSecurityDefinition("Bearer", new ApiKeyScheme
  8. {
  9. In = "header",
  10. Description = "请键入JWT Token,格式为'Bearer '+你的Token。",
  11. Name = "Authorization",
  12. Type = "apiKey"
  13. });
  14. // 网上为全局API添加认证参数的方法
  15. // c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>> {
  16. // { "Bearer", Enumerable.Empty<string>() },
  17. // });
  18. // 在过滤器中为需要认证的API添加对应参数
  19. // 过滤器的定义见下文
  20. c.OperationFilter<AuthorizationHeaderOperationFilter>();
  21. });

这里值得说一下的是,网上普遍都是全局添加认证参数,导致一些不需要认证的API也被打上了标识,这在Swagger 控制台中影响倒不大,但在后续的导出API时就麻烦了,所有在这里,我使用自定义过滤器的方式来只为需要认证的API添加认证参数。

根据上文,我们先定义一个AuthorizationHeaderOperationFilter类,它需要实现IOperationFilter接口,类定义如下:

  1. /// <summary>
  2. /// 判断是否需要添加Authorize Header
  3. /// </summary>
  4. public class AuthorizationHeaderOperationFilter : IOperationFilter
  5. {
  6. /// <summary>
  7. /// 为需要认证的Operation添加认证参数
  8. /// </summary>
  9. /// <param name="operation">The Swashbuckle operation.</param>
  10. /// <param name="context">The Swashbuckle operation filter context.</param>
  11. public void Apply(Operation operation, OperationFilterContext context)
  12. {
  13. // 获取对应方法的过滤器描述
  14. // 应该也就是所添加的Attribute
  15. var filterPipeline = context.ApiDescription.ActionDescriptor.FilterDescriptors;
  16. // 判断是否添加了AuthorizeFilter
  17. // 也就是[Authorize]
  18. var isAuthorized = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is AuthorizeFilter);
  19. // 判断是否添加了IAllowAnonymousFilter
  20. // 也就是[AllowAnonymous]
  21. var allowAnonymous = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is IAllowAnonymousFilter);
  22. // 仅当需要认证且不是AllowAnonymous的情况下,添加认证参数
  23. if (isAuthorized && !allowAnonymous)
  24. {
  25. // 若该Operation不存在认证参数的话,
  26. // 这个Security将是null,而不是空的List
  27. if (operation.Security == null)
  28. operation.Security = new List<IDictionary<string, IEnumerable<string>>>();
  29. // 添加认证参数
  30. operation.Security.Add(new Dictionary<string, IEnumerable<string>>
  31. {
  32. { "Bearer", new string[] { } }
  33. });
  34. }
  35. }
  36. }

重新生成后运行,应该就可以看到需要认证的API都带上了一把小锁。

注意事项

虽说配置并不算难,但还是需要注意一些地方。

  1. 注意写好XML注释

    之前也说了,Swagger的注释是根据XML文档生成的,反过来说,如果你没写XML注释,Swagger上也就是不会有注释的。

    另外,在你启用XML文档输出之后,VS也会很贴心的为你把没有写XML注释的地方都标为Warning。╮(╯▽╰)╭,所以安心的把注释都补一遍吧。

  2. 为参数添加数据注解

    Swagger是支持部分数据注解的,比如[Required]之类的。

    结合[ApiController]自带的模型验证功能,岂不美哉。

  3. 将XML文档复制到输出目录

    若你在发布应用后发现XML不见了,那可能就是你没有为XML文档文件配置复制到输出目录的属性。

    打开资源管理器,右键对应的文件,我们在属性中可以看到有复制到输出目录的属性,将其设置为始终复制就Ok。

以上就是我最近所用到的Swagger的一些功能。

导出微信小程序可用的API

在一开始也说了,使用Swagger的主要目的就是方便小团队的沟通,但事实上,因为我们前端的人少(大家都是CSS鬼才),导致我们开发新API的速度往往比前端进度快,没几天前端那边就需要更新一下API的库(将小程序的CallBack封装成Promise)。

因此,就有了根据Swagger自动生成Js可用的API文件的想法,其实想法的本身是来自于Abp项目的设计(真的很优秀),但出于一些方面的考虑,我们姑且还没采用Abp。

随后,就是查找资料了,确实Swagger有这方面的支持,其中官方关于Js的库是完全动态的,但可惜不适用于小程序。然后,就发现了第三方的swagger-js-codegen,可用于生成静态的Js代码,且提供了自定义模板的功能。网上也不少基于这个库的其他模板,比如说axios之类的,但没有适用于微信小程序的,不过问题不大,模板是基于mustache的,动手撸就是了。

模板代码有点长就不在这里放出了,大家还请移步GitHub

这里我就简单说下大致思路,

模板本身是基于原来的nodejs模板改的,我们所需做的就是将http请求部分的代码改为使用wx.request,如下简单的封装即可:

  1. /**
  2. * HTTP Request
  3. * @method
  4. * @name {{&className}}#request
  5. * @param {string} method - HTTP 请求方法
  6. * @param {string} url - 开发者服务器接口地址
  7. * @param {object} data - 请求的参数
  8. * @param {object} headers - 设置请求的 header ,默认为 application/json
  9. */
  10. request(method, url, parameters, data, headers){
  11. return new Promise((resolve, reject) => {
  12. wx.request({
  13. url: url,
  14. data: data,
  15. header: headers,
  16. method: method,
  17. success: res => {
  18. if(res.statusCode >= 200 && res.statusCode <= 299) {
  19. resolve(res.data)
  20. } else {
  21. reject(res)
  22. }
  23. },
  24. fail: e => reject(e)
  25. })
  26. })
  27. }

对应method的话,基本没怎么改,只根据微信小程序所有参数都是传递给data,做了点简化。

对于认证部分,根据我们自己的需求,换成了这样的实现:

  1. new Promise((resolve, reject) => {
  2. this.authenticate()
  3. .then(token => {
  4. headers['Authorization'] = 'Bearer ' + token;
  5. resolve(this.request('{{method}}', domain + path, parameters, data, headers))
  6. })
  7. })

其中this.authenticate是由外部传入的function,返回一个包含TokenPromise

导出后,在小程序中的使用就类似于:

  1. import API from './api.js'
  2. api = new API('http://localhost:5000')
  3. api.setAuthenticate(function () {
  4. return new Promise((resolve, reject) => {
  5. // 你的认证逻辑
  6. resolve(token)
  7. })
  8. })

然后,就可以开心地调用各种方法了。

最后,再放一遍Demo的链接:https://github.com/yiluomyt/swagger-wxopen-codegen-template,发现有问题欢迎提Issue。

Swagger 导出API的更多相关文章

  1. swagger 生成 api 文档 html

    https://cloud.tencent.com/developer/article/1332445 使用Swagger2Markup实现导出API文档 飞狗发表于专注于主流技术和业务订阅 2.4K ...

  2. 使用swagger生成API说明文档

    使用swagger生成API说明文档本文由个人总结,如需转载使用请标明原著及原文地址没有导出!!!!!不要整天给我留言导出呢,那个是你们百度的时候下面的推荐文章带的关键字,要做导出从swagger取数 ...

  3. 在ASP.NET Core Web API上使用Swagger提供API文档

    我在开发自己的博客系统(http://daxnet.me)时,给自己的RESTful服务增加了基于Swagger的API文档功能.当设置IISExpress的默认启动路由到Swagger的API文档页 ...

  4. Core Web API上使用Swagger提供API文档

    在ASP.NET Core Web API上使用Swagger提供API文档   我在开发自己的博客系统(http://daxnet.me)时,给自己的RESTful服务增加了基于Swagger的AP ...

  5. 导出api文档

    Export,选中项目或者需要导出api的类,右键 java-->javadoc configure,选择C:\Program Files\Java\jdk1.6.0_29\bin\javado ...

  6. 用Swashbuckle给ASP.NET Core的项目自动生成Swagger的API帮助文档

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:用Swashbuckle给ASP.NET Core的项目自动生成Swagger的API帮助文档.

  7. 从壹开始前后端分离 [.netCore 填坑 ] 三十四║Swagger:API多版本控制,带来的思考

    前言 大家周二好呀,.net core + Vue 这一系列基本就到这里差不多了,今天我又把整个系列的文章下边的全部评论看了一下(我是不是很负责哈哈),提到的问题基本都解决了,还有一些问题,已经在QQ ...

  8. ASP.NET Core WebApi使用Swagger生成api说明文档看这篇就够了

    引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必是件很痛苦的事情吧,但文档又必须写,而且文档的格式如果没有具体要求的话,最终完成的文档则完全取决于开发者 ...

  9. SpringBoot+Swagger整合API

    SpringBoot+Swagger整合API Swagger:整合规范的api,有界面的操作,测试 1.在pom.xml加入swagger依赖 <!--整合Swagger2配置类--> ...

随机推荐

  1. django的流程分析

    首先实现一个前端输入网址,后端返回不同的html文件的步骤 一.配置django 1.创建工程 2.创建app 二.配置setting 1.配置templates路径 2.注释跨站请求 三.配置pro ...

  2. Bom对象介绍

    1.windows对象 1.windows对象 1_1.alert:显示一段消息和确认按钮的弹出的警告框 我们平时用的alert的全称就是 window.alert("hahah" ...

  3. handler------post传送方式

    package com.qianfeng.gp08_day26_hanlder2; import android.os.Bundle; import android.os.Handler; impor ...

  4. StringUtils学习

    commons-lang3-3.5.jar

  5. oracle基本查询入门(二) 子查询

    一.子查询语法 SELECT select_list FROM table WHERE expr operator (SELECT select_list FROM table); 子查询在主查询之前 ...

  6. [freeCodeCamp] Start a Nodejs Server - Complete "Make it Modular"

    _/home/ubuntu/.nvm/versions/node/v4.4.5/lib/node_modules/learnyounode/exer cises/make_it_modular/sol ...

  7. asp.net状态保持

    1.首先如果不是asp.net webform而只是一个纯粹的html页面和ashx一般处理程序的话,因为http协议的无状态,每一次的页面请求都会重新实例化一个页面对象(注意实例化页面对象其实是通过 ...

  8. Ckeditor上传图片返回的JS直接显示出来,未执行!!!

    Ckeditor上传图片网上有很多教程. 下面是我今天下午遇到的一个坑...自己挖的坑. 在conotroller里 我开始习惯性的 response.setContentType("app ...

  9. crontab误删除

    命令如下: cat /var/log/cron* | grep -i "`which cron`" > ./all_temp cat ./all_temp | grep -v ...

  10. VS2010 MFC对话框程序用CButtonST给按钮添加图标

    也许是VS版本的关系,CButtonST中的BCMenu两个文件是无法编译通过的.   1.拷贝下载的CButtonST(我下载的v3.9)中的BtnST.h和BtnST.cpp文件到自己项目目录下. ...