koa-swagger-decorator:基于注解根據API自動生成可視化swagger文檔

背景介紹

在前后端分離的架構下,后端如果能夠維護一份與代碼實時同步更新,并且可讀性良好的文檔,可以極大的減少前后端溝通交流的成本,也可以提升前后端的開發效率。

Swagger是一種Rest API的 簡單但強大的表示方式,標準的,語言無關,這種 表示方式不但人可讀,而且機器可讀。具體的定義可以參考 Swagger Definition

通過使用 Swagger UI 使得用 swagger 規范的接口文檔可以被很好的可視化,并且直接在web網頁中進行接口的調試,既方便了后端開發時的調試,也使得前端對接口有了更加清楚明確的理解,基本可以讓我們拋棄 postman 等接口調試工具了。

簡介

本文主要想要探討的是在快速迭代的中小型項目的敏捷開發中,維護接口文檔的最優方式,所以會更傾向于保證開發的效率,并且同時能夠提供可讀性良好,實時更新的接口文檔。

本文將介紹幾種基于 swagger 的維護項目接口文檔的方式,并分析各種方式的優劣,并且提出了一種基于decorator來自動生成swagger json文檔的方法。

項目地址
npm/koa-swagger-decorator
github/koa-swagger-decorator

直接按照 swagger 規范 使用 yaml 的格式書寫文檔

這是最基本的使用 swagger 維護文檔的方法。文檔與后端代碼和業務邏輯完全解耦。雖然使用 yaml 的格式來書寫文檔一定程度上保證了機器的可讀性,也保證了人的可讀性,但是當項目體積逐漸變大,維護成本依然很高,對于某個接口的細微修改,都需要重新去定位到接口文檔中的對應位置進行修改,并且接口文檔很有可能被忘記修改。

此外它還有一個很大的問題,就是重復的代碼太多了,只有schema可以被復用,其他的都需要大量的復制粘貼才能完成。所以一開始這個方案就被排除了。

使用 swagger-jsdoc 維護文檔

swagger-jsdoc 使得我們可以將swagger融入到基于JsDoc的注釋當中去,這確實是一個對代碼侵入性較小,同時能夠大大方便對項目文檔維護的方式。
示例如下:

/**
 * @swagger
 * /logger/apps:
 *   get:
 *     summary: 獲取有日志記錄的應用
 *     description: 獲取有日志記錄的應用
 *     tags:
 *       - Logger
 *     parameters:
 *       - name: appName
 *         in: query
 *         required: true
 *         description: 應用名稱
 *         type: string
 *       - name: userId
 *         in: query
 *         required: true
 *         description: 用戶id
 *         type: string
 *     responses:
 *       200:
 *         description: 成功獲取
 */
router.get('/apps', async (req, res, next) => {
  try {
    const result = ['自定義字段'];

    return res.send({ result });
  } catch (err) {
    next(err);
  }
});

在注釋中使用@swagger開頭,然后就可以按照 swagger 的語法來進行接口的定義。這樣子極大地方便了文檔的書寫和修改,在程序員對接口進行修改之后,也不至于忘記維護接口文檔,同時可以更加方便的實時的調試自己的接口。

基于swagger ui 可以自動生成如下的接口文檔界面

image.png

并且可以直接在該界面中調試接口

image.png

基于 swagger-jsdoc 的解決方案對于快遞迭代的中小型項目來說已經是一個不錯的選擇了。我們基于這樣的方案也開發的較長的一段時間,相對于原來的接口文檔維護的方案可以說是體驗大大的提升了。但是依然不是一個十分理想的解決方案。

優點:
  1. 文檔不再與代碼分離,每個接口的定義都分布在對于的接口路由處,方便修改維護,減輕文檔維護的成本
  2. 實際上文檔與代碼依然是解耦的,文檔的定義不影響代碼的邏輯,開發時依然只需要專注于業務邏輯。
缺點:
  1. 文檔與代碼解耦有其優勢但也有其缺陷。接口文檔理論上應該是與業務邏輯有一定的一致性的,比如當我們需要對一個接口的路由進行修改的時候,我們需要對于的修改swagger-jsdoc中的定義,這其實也是冗余的步驟。

  2. 有很多重復的文檔書寫工作。比如response相關的參數,比如可能很多接口會有相似的query參數,但是我們依然每次都得進行一次復制粘貼來進行新的接口的swagger的定義。

  3. 報錯信息不清晰。對于一個需要接受的參數很多的接口,swagger文檔會寫的比較長,當在swgger文檔中出現語法錯誤,縮進錯誤時,錯誤提示很不清楚,無法直接定位到出錯點。

一些想法

經過多 swagger-jsdoc 一段時間的時候,我們認為我們需要的這么一個工具:能提供類似swagger-jsdoc的文檔書寫方式,但是同時能夠相比于在注釋中書寫的方式,提供與代碼一定的耦合性。進一步減輕維護文檔的負擔,提升開發效率。

基于注解的swagger 文檔書寫形式

借鑒 java 的 spring 框架中使用注解的形式來生成文檔的形式,我們考慮在 node 中 利用 decorator 的特性,實現類似的功能,但是并不對代碼產生更多的侵入性的改造,保持后端API服務的簡潔性。

koa-swagger-decorator庫所提供的功能:

  1. 提供路由定義的功能
  2. 提供參數驗證的功能
  3. 基于API生成swagger文檔

直接來看最終實現的形式

// 定義可復用的schema
const userSchema = {
  type: 'object',
  properties: {
    name: { type: 'string' },
    gender: { type: 'string' }
  }
};


  @request('post', '/users')
  @tag('User')
  @summary('創建用戶')
  @body([{
    name: 'data',
    description: '用戶信息',
    schema: userSchema,
  }])
  static async postUser(ctx) {
    const body = ctx.request.body;
    ...
    ctx.body = { result: body };
  }

查看完整示例請看:Github/koa-swagger-decorator
項目需要koa2+ koa-router 的依賴

通過這樣的方式,我們就可以拋棄使用 yaml 的語法書寫文檔了,可以直接用 js 的對象來維護文檔,并且自然的支持各個對象的復用了。

這個方式對于原有rest api實現方式而言唯一的一個改動就是:由于注解只能在Class中使用,所以我們只能將處理函數放在Class中,并且使用靜態方法的方式來使用,這是相對之前的開發模式最大的改變,其他的體驗依然基本保持一致。

最后

該項目現在已經支持參數的驗證和自動化swagger文檔的構建。未來將提供OpenApi 3.0版本的支持

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容