如何利用 Node 書寫 API 文件

sensitivemix發表於2019-04-13

為什麼需要 API 文件

目前大的環境下面,基本服務都以單體服務轉換成前後端分離的服務,客戶端作為呼叫方,服務端需要給予到呼叫方通俗易懂的文件。

常見 API 文件有哪些

  1. gitbook

Modern documentation format and toolchain using Git and Markdown

圖片

  • Usage
  • 優點:
    • 類似書籍的管理方式(適合寫書)
    • 支援多人協作,支援儲存在 Github 中
    • 支援 Build 成靜態網頁,部署方便
  • 缺點:
    • 需要熟悉 **Markdown **語法,不是實時生成,需要使用 Git-cli 打包檔案
    • 以一本書籍作為起點,只能放到單個專案中
  • 總結:適合寫書籍,不太適合 API 開發文件
  1. jsdoc

An API documentation generator for JavaScript.

圖片

  • Usage
  • 優點:
    • 功能豐富,支援引入塊狀註釋(Block Tags
    • 功能豐富,支援內聯註釋(Inline Tags
    • 強大的社群支援,各個平臺支援 jsdocs 外掛
  • 缺點:
    • 有一定的學習成本,需要學習它的塊狀註釋使用方式
    • UI 只能單專案使用,每個專案的 DOC UI 獨立
  • 線上樣例(better-docs tui-jsdoc-template)
  • 總結:適合深度定製專案,比如說我們對外開放 API 給開發者使用。
  1. swagger-jsdoc

Generates swagger doc based on JSDoc.

圖片

  • Usage
  • 優點:
    • 集合 Swagger,支援按照類似 JSDoc 方式生成文件
    • 支援錯誤定位,如果註釋書寫錯誤,能夠丟擲具體的錯誤棧
    • 支援 CLI,自由選擇檔案輸出位置
  • 缺點:
    • 書寫格式不友好,強格式要求,對於新手來說不容易上手,官方樣例較少,很多語法需要對於 Swagger YAML 格式,自己理解進行對映
    • 沒有能夠完成安裝 JSDoc 格式來書寫註釋,更傾向於 YAML 檔案
  1. doc-generators

simple generator handler for swagger

/**
 * @typedef Product
 * @property {integer} id
 * @property {string} name.required - Some description for product
 * @property {Array.<Point>} Point
 */

/**
 * This function comment is parsed by doctrine
 * sdfkjsldfkj
 * @route POST /users
 * @param {Point.model} point.body.required - the new point
 * @group foo - Operations about user
 * @param {string} email.query.required - username or email
 * @param {string} password.query.required - user's password.
 * @param {enum} status.query.required - Status values that need to be considered for filter - eg: available,pending
 * @operationId retrieveFooInfo
 * @produces application/json application/xml
 * @consumes application/json application/xml
 * @returns {Response.model} 200 - An array of user info
 * @returns {Product.model}  default - Unexpected error
 * @returns {Array.<Point>} Point - Some description for point
 * @headers {integer} 200.X-Rate-Limit - calls per hour allowed by the user
 * @headers {string} 200.X-Expires-After - 	date in UTC when token expires
 * @security JWT
 */
複製程式碼
  • Usage
  • 優點:
    • 支援整合 Swagger,支援按照類似 JSDoc 方式生成文件
    • 友好的文件的註釋,貼合 IDE 函式註釋
  • 缺點:
    • 實現可用的基礎上,需要支援到 IDE,方便一鍵生成,支援自動化

Example

/**
 * verify quarantine site
 * @route POST /ui/quarantine/v1/verify_od_dedicated_quarantine_site
 * @group quarantine
 * @param {QuarantineJSON.model} body.body.required - post body
 * @returns {object} 200 - An array of handler info
 * @returns {Error} 400 - invalid site
 * @returns {Error} 500 - internal error
 */
/**
 * JSON parameters require a model. This one just has "name"
 * @typedef QuarantineJSON
 * @property {string} site.required - quarantine site info
 */
    server.post('/ui/quarantine/v1/verify_od_dedicated_quarantine_site', middleware.other.verifyLoginInfo,
        rbac.quarantine.write, quarantine.verifyOdDedicatedQuarantineSite);
複製程式碼
/**
 * HTTP API statistics
 * @route GET /monit/v1/metric
 * @group monit
 * @param {string} sort.query - asc | desc
 * @param {string} direction.query - count | avarageMillisecondCost | routeName
 * @returns {object} 200 - An array of user info
 * @returns {metrics.model} default - Unexpected error
 */
/**
 * @typedef metrics
 * @property {string} routeName.required - 'getuiadminv1company_plans'
 * @property {number} count.required - route invoke times
 * @property {number} avarageMillisecondCost.required - route avg second cost
 */

server.get("/monit/v1/metric", validator.query({
    type: 'object',
    properties: {
        sort: { type: 'string', enum: ['count'] },
        direction: { type: 'string', enum: ['asc', 'desc'] }
    }
}), monitService.apiMetricHandlers);
複製程式碼

專案地址:github.com/SensitiveMi…

相關文章