Swagger 搭建 API 文档管理平台

API 文档是前后端对接的基本,但如果还停留在手写文档的阶段,那就真的太 out 了。大家可能也尝试过各种 API 接口管理的工具,比如 postman 、apizza 等,但个人使用下来还是感觉麻烦了,长期来看我是拒绝的。

reject

从目前 API 文档生成及管理上来看,Swagger 可算是不错的框架。今天来介绍一下 Swagger 的使用,以下使用 .NETCore Web API 为例,其他语言也类似,最终都是依赖生成的 json/yaml 文件。

文档生成

内嵌代码方式

  1. 新建 ASP.NET Core Web 应用程序,选择 API 类型

  2. NuGet 安装 Swashbuckle.AspNetCore

    Install-Package Swashbuckle.AspNetCore
    
  3. 在 Startup.cs 中的 ConfigureServices 和 Configure 方法添加 Swagger 相关代码

    public void ConfigureServices(IServiceCollection services)
    {
      services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
          
      // swagger.json 文档生成参数配置
      services.AddSwaggerGen(options =>
      {
        options.SwaggerDoc("v1", new Info
        {
          Title = "SwaggerTest接口文档",
          Version = "1.0.0"
        });
        
        options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "SwaggerTest.XML"));
      });
    }
    
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
      if (env.IsDevelopment())
      {
        app.UseDeveloperExceptionPage();
      }
    
      app.UseMvc();
    
      app.UseSwagger();
      
      // 通过SwaggerUI展示
      app.UseSwaggerUI(options =>
      {
        options.SwaggerEndpoint("/swagger/v1/swagger.json", "SwaggerTest");
      });
    }
    
  4. 项目属性中的 ”生成“ 勾选 “XML 文档文件” (Debug 和 Release 两种模式下都勾选上)。这一步的目的是将代码注释生成文档,所以接口方法及参数都务必加上完整的注释

    build xml

  5. 运行项目,访问 http://localhost:62654/swagger/index.html

    swagger ui by code

以上方式使用起来非常简单,但个人觉得存在以下问题:

  1. Startup 中需要加入 Swagger 相关的一些代码,不够整洁

  2. 如果有多个 API 服务,每个服务都需要添加类似代码,而且每个服务的文档地址独立,不能统一管理

非内嵌代码方式

Swagger UI 本身是一个可以单独使用的前端项目。从 UseSwaggerUI 的参数配置来看:

app.UseSwaggerUI(options =>
{
  options.SwaggerEndpoint("/swagger/v1/swagger.json", "SwaggerTest");
});

其实只要将 "/swagger/v1/swagger.json" 这个文件引用进去即可,所以只需存在一种可以根据项目的 dll 文件生成 swagger.json 的方式,然后把生成的 swagger.json 引用到 Swagger UI 。NSwag 恰好可以满足这个需求。

抛开内嵌代码的方式,假设现在是一个全新的 Web API 项目。

  1. 下载 NSwag ,在 Downloads 中下载 NSwag command line tools。如下载后解压地址为: C:\Users\Administrator\Downloads\NSwag\

  2. 在项目根目录下新建 bat 文件并添加脚本,执行生成 swagger.json (windows 环境

    :: 生成的文档名,每个项目最好是唯一的
    SET FILE_NAME=swaggerTest
    :: 项目dll地址
    SET SOURCE_DLL=bin\Release\netcoreapp2.1\publish\SwaggerTest.dll
    :: 文档生成的目标文件夹
    SET TARGET_DIR=D:\ApiDoc\public\docs\
    
    :: Swagger文档配置
    
    :: 标题
    SET TITLE=SwaggerTest接口文档
    :: 描述
    SET DESCRIPTION=SwaggerTest接口文档描述
    :: 版本
    SET VERSION=1.0.0
    :: 接口测试请求的host地址,不同的api服务有不同的host
    SET HOST=localhost:5000
    
    :: 通过 dotnet-nswag 执行生成命令
    dotnet C:\Users\Administrator\Downloads\NSwag\NetCore21\dotnet-nswag.dll webapi2swagger /assembly:"%SOURCE_DLL%" /AspNetCore:true /output:%TARGET_DIR%%FILE_NAME%.json /InfoTitle:"%TITLE%" /InfoDescription:"%DESCRIPTION%" /InfoVersion:%VERSION% /ServiceHost:%HOST% 
    

bat 脚本执行完成后,在 D:\ApiDoc\public\docs\ 目录下就会多出一个 swaggerTest.json,以这种方式我们并不需要修改任何代码。到目前为止,API 文档对应的 json 文件就有了,接下来就是把它通过 Swagger UI 展示出来。假设每个 API 项目都生成一个 json 文件到指定的目录,而 Swagger UI 本身支持配置多个文档 url 地址,这就意味着可以搭建出了一个 API 文档管理平台。

API 文档管理平台

文档管理

  1. 下载 Swagger UI 并解压

  2. 搭建一个 Node.js 项目,可使用 Express 或者 Koa 框架(其他语言的项目也可以,任意选择)

    1. 将 swagger-ui dist 文件夹下的文件全部复制到项目的 public 文件夹下

    2. 安装 express

    3. 新建 index.js,添加如下代码

      const express = require('express');
      const app = express();
      
      app.use('/', express.static('public'));
      
      app.listen(3000, function () {
        console.log('app listening on http://localhost:3000');
      });
      
    4. 启动服务

      node index.js
      

完成以上步骤,Swagger UI 的站点就搭建完成了,访问 http://localhost:3000 会出现一个默认的 API 接口文档页面。

打开 public/index.html 会发现有这么一段代码:

const ui = SwaggerUIBundle({
  url: "https://petstore.swagger.io/v2/swagger.json",
  ...
})

这里的 url 配置了一个默认的 swagger.json文件的地址,所以我们只需要把 url 替换成上面生成的 swaggerTest.json 地址就可以了,将 swaggerTest.json 复制到 public/docs 目录下

swagger file
const ui = SwaggerUIBundle({
  url: "./docs/swaggerTest.json",
  ...
})
wagger ui by tool

如果有多个 json 文件就不能使用 url 参数,需要修改成 urls 参数,具体可参考 Swagger UI 参数配置,为了不需要每次手动调整 urls,所以需要动态读取 docs 文件夹下的文件,生成的文档只需要传到这个目录下就可以直接查看和测试。

在 index.js 增加一个接口:

app.get('/getDocs', function (req, res) {
  let docFileInfos = [];
  let pathDir = __dirname + '/public/docs';
  try {
    let fileNames = fs.readdirSync(pathDir);
    fileNames.forEach(function (fileName) {
      let data = fs.readFileSync(pathDir + '/' + fileName, 'utf8');
      data = data.trim();
      let json = JSON.parse(data);
      docFileInfos.push({
        url: './docs/' + fileName,
        name: json.info.title
      });
    });
  } catch (err) {
    console.log(err);
  }
  res.send(docFileInfos);
});

public/index.html 引入 axios,并调用 getDocs 接口获取结果,将 response.data 赋给 SwaggerUIBundle 的 urls 参数。

axios.get('/getDocs')
  .then(function (response) {
    if (response.status === 200 && response.data.length) {
      ...
    }
  });

当存在多个 json 文件的时候,可以从下拉选项中进去切换

multi swagger file

参考链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容