摘要:注解方式為應(yīng)用動態(tài)生成文檔目前我司服務(wù)端應(yīng)用程序框架主要采用了與,而因為今年有很多的調(diào)研階段的產(chǎn)品線發(fā)布,持續(xù)部署接口文檔以及線上質(zhì)量監(jiān)控這三個問題愈發(fā)突出。
swagger-decorator:注解方式為 Koa2 應(yīng)用動態(tài)生成 Swagger 文檔swagger-decorator:注解方式為 Koa2 應(yīng)用自動生成 Swagger 文檔 從屬于筆者的服務(wù)端應(yīng)用程序開發(fā)與系統(tǒng)架構(gòu),記述了如何在以 Koa2 與 koa-router 開發(fā)服務(wù)端應(yīng)用時,通過自定義 swagger-decorator 庫來實現(xiàn)類 Spring-Boot 中注解方式動態(tài)生成 Swagger 標準的接口文檔。
目前我司服務(wù)端應(yīng)用程序框架主要采用了 Java Spring 與 Node.js,而因為今年有很多的調(diào)研階段的產(chǎn)品線 Demo 發(fā)布,持續(xù)部署、接口文檔以及線上質(zhì)量監(jiān)控這三個問題愈發(fā)突出。本文則主要針對接口文檔的實時發(fā)布進行一些探討;在前后端分離的今天,即使是由單人縱向負責某個業(yè)務(wù)流,也需要將前后端交互的接口規(guī)范清晰地定義并且發(fā)布,以保證項目的透明性與可維護性。理想的開發(fā)流程中,應(yīng)當在產(chǎn)品設(shè)計階段確定好關(guān)鍵字段命名、數(shù)據(jù)庫表設(shè)計以及接口文檔;不過實際操作中往往因為業(yè)務(wù)的多變性以及人手的缺失,使得接口的定義并不能總是實時地在項目成員之間達成一致。如果要讓開發(fā)人員在更改接口的同時花費額外精力維護一份開發(fā)文檔,可能對于我司這樣的小公司而言存在著很大的代價與風險。軟件開發(fā)中存在著所謂 Single Source of Truth 的原則,我們也需要盡量避免文檔與實際實現(xiàn)的不一致造成的團隊內(nèi)矛盾以及無用的付出。綜上所述,我們希望能夠在編寫后臺代碼、添加注釋的同時,能夠自動地生成接口文檔;筆者比較熟悉 Spring 中以注解方式添加 Swagger 文檔的模式,不過 Java 庫的抽象程度一般較高,用起來也不怎么順手。筆者在編寫我司 node-server-boilerplate 根據(jù)自己的想法設(shè)計了 swagger-decorator。此外,項目中使用 Flow 進行靜態(tài)類型檢測,并且遵循我司內(nèi)部的 JavaScript 編程樣式指南。
我們可以使用 npm 或者 yarn 安裝 swagger-decorator,需要注意的是,因為使用了注解,因此建議是配置 Webpack 與 Babel,不熟悉的同學可以直接參考 node-server-boilerplate :
$ yarn add swagger-decorator # 依賴于 Babel 的 transform-decorators-legacy 轉(zhuǎn)換插件來使用 Decorator $ yarn add transform-decorators-legacy -D
安裝完畢之后,我們需要對項目中使用的路由進行封裝。目前筆者只是針對 koa-router 中的路由對象進行封裝,未來若有必要可以針對其他框架的路由解決方案進行封裝。我們首先需要做的就是在路由定義之前使用 wrappingKoaRouter 函數(shù)修飾 router 對象:
import { wrappingKoaRouter } from "swagger-decorator"; ... const Router = require("koa-router"); const router = new Router(); wrappingKoaRouter(router, "localhost:8080", "/api", { title: "Node Server Boilerplate", version: "0.0.1", description: "Koa2, koa-router,Webpack" }); //定義默認的根路由 router.get("/", async function(ctx, next) { ctx.body = { msg: "Node Server Boilerplate" }; }); //定義用戶處理路由 router.scan(UserController);
該函數(shù)的參數(shù)說明如下,對于 info 的結(jié)構(gòu)參考這里:
/** * Description 將 router 對象的方法進行封裝 * @param router 路由對象 * @param host API 域名 * @param basePath API 基本路徑 * @param info 其他的 Swagger 基本信息 */ export function wrappingKoaRouter( router: Object, host: string = "localhost", basePath: string = "", info: Object = {} ) {}
值得一提的是,在封裝 router 時,筆者自定義了 scan 方法,其能夠根據(jù)自動遍歷目標類中的自定義方法,有點類似于 Java 中的 ComponentScan:
/** * Description 掃描某個類中的所有靜態(tài)方法,按照其注解將其添加到 * @param staticClass */ router.scan = function(staticClass: Function) { let methods = Object.getOwnPropertyNames(staticClass); // 移除前三個屬性 constructor、name methods.shift(); methods.shift(); methods.shift(); for (let method of methods) { router.all(staticClass[method]); } };
準備工作完成之后,我們即可以開始定義具體的接口控制器;筆者不喜歡過多的封裝,因此這里選用了類的靜態(tài)方法來定義具體的接口函數(shù),整個 Controller 也只是樸素函數(shù)。下面筆者列舉了常見的獲取全部用戶列表、根據(jù)用戶編號獲取用戶詳情、創(chuàng)建新用戶這幾個接口的文檔注釋方式:
import { apiDescription, apiRequestMapping, apiResponse, bodyParameter, pathParameter, queryParameter } from "swagger-decorator"; import User from "../entity/User"; /** * Description 用戶相關(guān)控制器 */ export default class UserController { @apiRequestMapping("get", "/users") @apiDescription("get all users list") @apiResponse(200, "get users successfully", [User]) static async getUsers(ctx, next): [User] { ... } @apiRequestMapping("get", "/user/:id") @apiDescription("get user object by id, only access self or friends") @pathParameter({ name: "id", description: "user id", type: "integer" }) @queryParameter({ name: "tags", description: "user tags, for filtering users", required: false, type: "array", items: ["string"] }) @apiResponse(200, "get user successfully", User) static async getUserByID(ctx, next): User { ... } @apiRequestMapping("post", "/user") @apiDescription("create new user") @bodyParameter({ name: "user", description: "the new user object, must include user name", required: true, schema: User }) @apiResponse(200, "create new user successfully", { status_code: "200" }) static async postUser(): number { ... } }
在對接口注解的時候,我們需要用實體類指明返回值或者請求體中包含的參數(shù)信息,因此我們也需要使用 swagger-decorator 提供的 entityProperty 注解來為實體類添加描述。值得一提的是,這里我們支持直接將 Object 作為描述對象的返回值,算是避免了 Java 中的一大痛點。
// @flow import { entityProperty } from "swagger-decorator"; /** * Description 用戶實體類 */ export default class User { // 編號 @entityProperty({ type: "integer", description: "user id, auto-generated", required: false }) id: string = 0; // 姓名 @entityProperty({ type: "string", description: "user name, 3~12 characters", required: true }) name: string = "name"; // 朋友列表 friends: [number] = [1]; // 屬性 properties: { address: string } = { address: "address" }; }
對于沒有添加注解的屬性,swagger-decorator 會自動根據(jù)其默認值來推測類型。然后我們就可以正常地啟動應(yīng)用,swagger-decorator 已經(jīng)自動地為 router 對象添加了兩個路由,其中 /swagger 指向了 Swagger UI:
而 /swagger/api.json 指向了 Swagger 生成的 JSON 文檔:
歡迎有興趣的朋友提出 ISSUE、指導意見或者希望納入的特性。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/83519.html
摘要:中基于的自動實體類構(gòu)建與接口文檔生成是筆者對于開源項目的描述,對于不反感使用注解的項目中利用添加合適的實體類或者接口類注解,從而實現(xiàn)支持嵌套地實體類校驗與生成等模型生成基于的接口文檔生成等等功能。 JavaScript 中基于 swagger-decorator 的自動實體類構(gòu)建與 Swagger 接口文檔生成是筆者對于開源項目 swagger-decorator 的描述,對于不反感使...
摘要:前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點分為新聞熱點開發(fā)教程工程實踐深度閱讀開源項目巔峰人生等欄目。對該漏洞的綜合評級為高危。目前,相關(guān)利用方式已經(jīng)在互聯(lián)網(wǎng)上公開,近期出現(xiàn)攻擊嘗試爆發(fā)的可能。 前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點;分為新聞熱點、開發(fā)教程、工程實踐、深度閱讀、開源項目、巔峰人生等欄目。歡...
摘要:其標準為前身是,提供強大的在線編輯功能,包括語法高亮錯誤提示自動完成實時預覽,并且支持用戶以格式撰寫導入導出轉(zhuǎn)換文檔。 團隊內(nèi)部RestAPI開發(fā)采用設(shè)計驅(qū)動開發(fā)的模式,即使用API設(shè)計文檔解耦前端和后端的開發(fā)過程,雙方只在聯(lián)調(diào)與測試時耦合。在實際開發(fā)和與前端合作的過程中,受限于眾多因素的影響,開發(fā)效率還有進一步提高的空間。本文的目的是優(yōu)化工具鏈支持,減少一部分重復和枯燥的勞動。 現(xiàn)狀...
摘要:前端日報精選常用實例的實現(xiàn)與封裝實現(xiàn)一個構(gòu)建基于的可擴展應(yīng)用規(guī)范翻譯從到中文開源中國兩級緩存實踐掘金中基于的自動實體類構(gòu)建與接口文檔生成某熊的全棧之路繼承總結(jié)教程中的五種組件形式掘金再說的問題前端開發(fā)前端每周清單第期正式 2017-07-18 前端日報 精選 javascript常用實例的實現(xiàn)與封裝實現(xiàn)一個 SwiperRekit 2.0 構(gòu)建基于React+Redux+React-r...
摘要:請注意,截至目前版本,用于的集成仍處于孵化階段,并且存在一些嚴重的錯誤和缺少的功能例如,請參閱此處和此處。響應(yīng)可以使用和注解來調(diào)整不同的響應(yīng)狀態(tài)及其有效結(jié)論允許您在創(chuàng)建數(shù)據(jù)庫驅(qū)動的時產(chǎn)生快速結(jié)果。 原文: Documenting a Spring Data REST API with Springfox and Swagger 使用Spring Date REST,你可以迅速為Spr...
閱讀 3485·2019-08-30 15:55
閱讀 2071·2019-08-30 15:44
閱讀 1490·2019-08-30 12:47
閱讀 767·2019-08-30 11:05
閱讀 1651·2019-08-30 10:54
閱讀 680·2019-08-29 16:07
閱讀 3599·2019-08-29 14:17
閱讀 2253·2019-08-23 18:31