使用 apiDoc 爲你的Node.js API 自動生成文檔[每日前端夜話0x78]html
瘋狂的技術宅 前端先鋒 前端
每日前端夜話0x78
每日前端夜話,陪你聊前端。
天天晚上18:00準時推送。
正文共:1511 字
預計閱讀時間: 5 分鐘
翻譯:瘋狂的技術宅
來源:jonathasnode
當你爲其餘開發人員(前端,桌面,移動等)開發 API 時,須要生成一份風格良好的文檔,以便他們知道能夠使用的內容和方式,這很是重要。git
爲此,在Node.js項目中,我一直在使用apiDoc【http://apidocjs.com/】,由於它可以從源代碼中的註釋生成HTML文檔。github
對於本文,我將使用我開發的 TODO List API 做爲示例。你能夠從這裏克隆或下載它【https://github.com/jonathas/todo-api】。typescript
在我關於使用 mocha 進行測試並使用 istanbul 進行代碼覆蓋測試的文章中【https://jonathas.com/tests-and-code-coverage-on-node-using-typescript-with-mocha-and-istanbul/】,我在 TODO List API 中顯示了 Task 端點的示例:npm
1import Task from "../controllers/tasks"; 2 3export = (app) => { 4 const endpoint = process.env.API_BASE + "tasks"; 5 app.post(endpoint, Task.create); 6 app.delete(endpoint + "/:id", Task.delete); 7 app.get(endpoint + "/:id", Task.getOne); 8 app.get(endpoint, Task.getAll); 9 app.put(endpoint + "/:id", Task.update); 10};
這表明了與系統中任務相關的全部端點。咱們怎樣才能使用它們呢?使用 API 的開發人員應該向每一個端點發送什麼數據呢?json
到如今爲止,他們除了去查看代碼以外沒有其餘方法能夠搞清楚,可是這些代碼不該該被用做這個目的。gulp
有了 apiDoc,咱們能夠用註釋來生成文檔。個人方法是在 routes 目錄下的文件中配置的每一個端點的前面編寫它們。當我提到如何配置和組織個人 Node.js 項目時,若是你不肯定我在說什麼請 點擊這裏【https://jonathas.com/tests-and-code-coverage-on-node-using-typescript-with-mocha-and-istanbul/】。api
使用註釋,咱們的任務端點(內部routes/tasks.ts)將以下所示:
1import Task from "../controllers/tasks"; 2 3export = (app) => { 4 5 const endpoint = process.env.API_BASE + "tasks"; 6 7 /** 8 * @api {post} /api/v1/tasks Create a task 9 * @apiVersion 1.0.0 10 * @apiName Create 11 * @apiGroup Task 12 * @apiPermission authenticated user 13 * 14 * @apiParam (Request body) {String} name The task name 15 * 16 * @apiExample {js} Example usage: 17 * const data = { 18 * "name": "Do the dishes" 19 * } 20 * 21 * $http.defaults.headers.common["Authorization"] = token; 22 * $http.post(url, data) 23 * .success((res, status) => doSomethingHere()) 24 * .error((err, status) => doSomethingHere()); 25 * 26 * @apiSuccess (Success 201) {String} message Task saved successfully! 27 * @apiSuccess (Success 201) {String} id The campaign id 28 * 29 * @apiSuccessExample {json} Success response: 30 * HTTPS 201 OK 31 * { 32 * "message": "Task saved successfully!", 33 * "id": "57e903941ca43a5f0805ba5a" 34 * } 35 * 36 * @apiUse UnauthorizedError 37 */ 38 app.post(endpoint, Task.create); 39 40 /** 41 * @api {delete} /api/v1/tasks/:id Delete a task 42 * @apiVersion 1.0.0 43 * @apiName Delete 44 * @apiGroup Task 45 * @apiPermission authenticated user 46 * 47 * @apiParam {String} id The task id 48 * 49 * @apiExample {js} Example usage: 50 * $http.defaults.headers.common["Authorization"] = token; 51 * $http.delete(url) 52 * .success((res, status) => doSomethingHere()) 53 * .error((err, status) => doSomethingHere()); 54 * 55 * @apiSuccess {String} message Task deleted successfully! 56 * 57 * @apiSuccessExample {json} Success response: 58 * HTTPS 200 OK 59 * { 60 * "message": "Task deleted successfully!" 61 * } 62 * 63 * @apiUse UnauthorizedError 64 */ 65 app.delete(endpoint + "/:id", Task.delete); 66 67 /** 68 * @api {get} /api/v1/tasks/:id Retrieve a task 69 * @apiVersion 1.0.0 70 * @apiName GetOne 71 * @apiGroup Task 72 * @apiPermission authenticated user 73 * 74 * @apiParam {String} id The task id 75 * 76 * @apiExample {js} Example usage: 77 * $http.defaults.headers.common["Authorization"] = token; 78 * $http.get(url) 79 * .success((res, status) => doSomethingHere()) 80 * .error((err, status) => doSomethingHere()); 81 * 82 * @apiSuccess {String} _id The task id 83 * @apiSuccess {String} name The task name 84 * 85 * @apiSuccessExample {json} Success response: 86 * HTTPS 200 OK 87 * { 88 * "_id": "57e8e94ea06a0c473bac50cc", 89 * "name": "Do the disehs", 90 * "__v": 0 91 * } 92 * 93 * @apiUse UnauthorizedError 94 */ 95 app.get(endpoint + "/:id", Task.getOne); 96 97 /** 98 * @api {get} /api/v1/tasks Retrieve all tasks 99 * @apiVersion 1.0.0 100 * @apiName GetAll 101 * @apiGroup Task 102 * @apiPermission authenticated user 103 * 104 * @apiExample {js} Example usage: 105 * $http.defaults.headers.common["Authorization"] = token; 106 * $http.get(url) 107 * .success((res, status) => doSomethingHere()) 108 * .error((err, status) => doSomethingHere()); 109 * 110 * @apiSuccess {String} _id The task id 111 * @apiSuccess {String} name The task name 112 * 113 * @apiSuccessExample {json} Success response: 114 * HTTPS 200 OK 115 * [{ 116 * "_id": "57e8e94ea06a0c473bac50cc", 117 * "name": "Do the disehs" 118 * }, 119 * { 120 * "_id": "57e903941ca43a5f0805ba5a", 121 * "name": "Take out the trash" 122 * }] 123 * 124 * @apiUse UnauthorizedError 125 */ 126 app.get(endpoint, Task.getAll); 127 128 /** 129 * @api {put} /api/v1/tasks/:id Update a task 130 * @apiVersion 1.0.0 131 * @apiName Update 132 * @apiGroup Task 133 * @apiPermission authenticated user 134 * 135 * @apiParam {String} id The task id 136 * 137 * @apiParam (Request body) {String} name The task name 138 * 139 * @apiExample {js} Example usage: 140 * const data = { 141 * "name": "Run in the park" 142 * } 143 * 144 * $http.defaults.headers.common["Authorization"] = token; 145 * $http.put(url, data) 146 * .success((res, status) => doSomethingHere()) 147 * .error((err, status) => doSomethingHere()); 148 * 149 * @apiSuccess {String} message Task updated successfully! 150 * 151 * @apiSuccessExample {json} Success response: 152 * HTTPS 200 OK 153 * { 154 * "message": "Task updated successfully!" 155 * } 156 * 157 * @apiUse UnauthorizedError 158 */ 159 app.put(endpoint + "/:id", Task.update); 160 161};
如你所見,咱們有 HTTP 方法的類型(post,put,get,delete)、端點地址、api 版本、它須要的權限類型、它須要的參數,還有若是用戶是未經受權的應該返回怎樣的響應和錯誤。
在官方網站【http://apidocjs.com/】中,你能夠查看註釋文檔和可用參數。
那麼這個 UnauthorizedError 來自哪裏呢?
有一些設置能夠用 apiDoc 完成,這個 UnauthorizedError 就是我常常要用到的。
在 routes 目錄中建立一個名爲 __apidoc.js 的文件,其中包含如下內容:
1// ----------------------------------------------------------- 2// General apiDoc documentation blocks and old history blocks. 3// ----------------------------------------------------------- 4 5// ----------------------------------------------------------- 6// Current Success. 7// ----------------------------------------------------------- 8 9 10// ----------------------------------------------------------- 11// Current Errors. 12// ----------------------------------------------------------- 13 14 15// ----------------------------------------------------------- 16// Current Permissions. 17// ----------------------------------------------------------- 18/** 19 * @apiDefine UnauthorizedError 20 * @apiVersion 1.0.0 21 * 22 * @apiError Unauthorized Only authenticated users can access the endpoint. 23 * 24 * @apiErrorExample Unauthorized response: 25 * HTTP 401 Unauthorized 26 * { 27 * "message": "Invalid credentials" 28 * } 29 */ 30 31// ----------------------------------------------------------- 32// History. 33// -----------------------------------------------------------
我還建立了另外一個文件,也在 routes 目錄中,名爲 apidoc.json
該文件包含如下內容(示例):
1{ 2 "name": "Test API - This is my API", 3 "version": "1.0.0", 4 "description": "This is my very powerful API", 5 "title": "Test API - This is my API", 6 "url": "https://testapi.com" 7}
生成文檔時,apiDoc 將會使用這兩個文件。
在爲每一個端點編寫註釋並配置好項目以後,咱們須要配置一個任務來生成文檔。
我用 gulp 來作到這一切。安裝所需的依賴項:
1npm i gulp gulp-apidoc --save-dev
而後在項目的根目錄中建立一個名爲 gulpfile.js 的文件。若是它已經存在,只需添加與 apiDoc 相關的部分:
1const gulp = require("gulp"); 2const apidoc = require("gulp-apidoc"); 3 4gulp.task("apidoc", (done) => { 5 apidoc({ 6 src: "./routes", 7 dest: "../docs/apidoc" 8 }, done); 9}); 10 11gulp.task("watch", () => { 12 gulp.watch(["./routes/**"], ["apidoc"]); 13});
你能夠將那裏的 「dest」 目錄更改成另外一個更適合你的目錄。這就是你但願生成輸出的位置。
如今你須要作的就是運行:
1gulp apidoc
以後,你只須要在上面 「dest」 中配置的目錄中打開 index.html 文件,就會看到相似這樣的內容):
其餘開發人員也能夠用 gulp 生成相同的內容,或者你甚至能夠經過 Nginx 爲生成的目錄提供Web服務。
在這本文中,咱們瞭解瞭如何使用註釋來記錄 API,並使用 apiDoc 爲它們生成 HTML 格式的文檔。
你是否還用了其餘軟件來爲你的 API 生成文檔,或者你是否以其餘方式使用 apiDoc?請在下面評論中留言討論!
原文:https://jonathas.com/documenting-your-nodejs-api-with-apidoc/