翻譯: 瘋狂的技術宅
原文:jonathas.com/documenting…
未經許可,禁止轉載!
當你為其他開發人員(前端,桌面,移動等)開發 API 時,需要生成一份風格良好的文檔,以便他們知道可以使用的內容和方式,這非常重要。
為此,在Node.js項目中,我一直在使用apiDoc,因為它能夠從源代碼中的注釋生成HTML文檔。
對于本文,我將使用我開發的 TODO List API 作為示例。你可以從這里克隆或下載它。
路由和注釋
在我關于使用 mocha 進行測試并使用 istanbul 進行代碼覆蓋測試的文章中,我在 TODO List API 中顯示了 Task 端點的示例:
import Task from "../controllers/tasks";export = (app) => {const endpoint = process.env.API_BASE + "tasks";app.post(endpoint, Task.create);app.delete(endpoint + "/:id", Task.delete);app.get(endpoint + "/:id", Task.getOne);app.get(endpoint, Task.getAll);app.put(endpoint + "/:id", Task.update);
};
復制代碼
這代表了與系統中任務相關的所有端點。我們怎樣才能使用它們呢?使用 API ??的開發人員應該向每個端點發送什么數據呢?
到現在為止,他們除了去查看代碼之外沒有其他方法可以搞清楚,但是這些代碼不應該被用作這個目的。
有了 apiDoc,我們可以用注釋來生成文檔。我的方法是在 routes 目錄下的文件中配置的每個端點的前面編寫它們。當我提到如何配置和組織我的 Node.js 項目時,如果你不確定我在說什么請 點擊這里。
使用注釋,我們的任務端點(內部routes/tasks.ts)將如下所示:
import Task from "../controllers/tasks";export = (app) => {const endpoint = process.env.API_BASE + "tasks";/*** @api {post} /api/v1/tasks Create a task* @apiVersion 1.0.0* @apiName Create* @apiGroup Task* @apiPermission authenticated user** @apiParam (Request body) {String} name The task name** @apiExample {js} Example usage:* const data = {* "name": "Do the dishes"* }** $http.defaults.headers.common["Authorization"] = token;* $http.post(url, data)* .success((res, status) => doSomethingHere())* .error((err, status) => doSomethingHere());** @apiSuccess (Success 201) {String} message Task saved successfully!* @apiSuccess (Success 201) {String} id The campaign id** @apiSuccessExample {json} Success response:* HTTPS 201 OK* {* "message": "Task saved successfully!",* "id": "57e903941ca43a5f0805ba5a"* }** @apiUse UnauthorizedError*/app.post(endpoint, Task.create);/*** @api {delete} /api/v1/tasks/:id Delete a task* @apiVersion 1.0.0* @apiName Delete* @apiGroup Task* @apiPermission authenticated user** @apiParam {String} id The task id** @apiExample {js} Example usage:* $http.defaults.headers.common["Authorization"] = token;* $http.delete(url)* .success((res, status) => doSomethingHere())* .error((err, status) => doSomethingHere());** @apiSuccess {String} message Task deleted successfully!** @apiSuccessExample {json} Success response:* HTTPS 200 OK* {* "message": "Task deleted successfully!"* }** @apiUse UnauthorizedError*/app.delete(endpoint + "/:id", Task.delete);/*** @api {get} /api/v1/tasks/:id Retrieve a task* @apiVersion 1.0.0* @apiName GetOne* @apiGroup Task* @apiPermission authenticated user** @apiParam {String} id The task id** @apiExample {js} Example usage:* $http.defaults.headers.common["Authorization"] = token;* $http.get(url)* .success((res, status) => doSomethingHere())* .error((err, status) => doSomethingHere());** @apiSuccess {String} _id The task id* @apiSuccess {String} name The task name** @apiSuccessExample {json} Success response:* HTTPS 200 OK* {* "_id": "57e8e94ea06a0c473bac50cc",* "name": "Do the disehs",* "__v": 0* }** @apiUse UnauthorizedError*/app.get(endpoint + "/:id", Task.getOne);/*** @api {get} /api/v1/tasks Retrieve all tasks* @apiVersion 1.0.0* @apiName GetAll* @apiGroup Task* @apiPermission authenticated user** @apiExample {js} Example usage:* $http.defaults.headers.common["Authorization"] = token;* $http.get(url)* .success((res, status) => doSomethingHere())* .error((err, status) => doSomethingHere());** @apiSuccess {String} _id The task id* @apiSuccess {String} name The task name** @apiSuccessExample {json} Success response:* HTTPS 200 OK* [{* "_id": "57e8e94ea06a0c473bac50cc",* "name": "Do the disehs"* },* {* "_id": "57e903941ca43a5f0805ba5a",* "name": "Take out the trash"* }]** @apiUse UnauthorizedError*/app.get(endpoint, Task.getAll);/*** @api {put} /api/v1/tasks/:id Update a task* @apiVersion 1.0.0* @apiName Update* @apiGroup Task* @apiPermission authenticated user** @apiParam {String} id The task id** @apiParam (Request body) {String} name The task name** @apiExample {js} Example usage:* const data = {* "name": "Run in the park"* }** $http.defaults.headers.common["Authorization"] = token;* $http.put(url, data)* .success((res, status) => doSomethingHere())* .error((err, status) => doSomethingHere());** @apiSuccess {String} message Task updated successfully!** @apiSuccessExample {json} Success response:* HTTPS 200 OK* {* "message": "Task updated successfully!"* }** @apiUse UnauthorizedError*/app.put(endpoint + "/:id", Task.update);};
復制代碼
如你所見,我們有 HTTP 方法的類型(post,put,get,delete)、端點地址、api 版本、它需要的權限類型、它需要的參數,還有如果用戶是未經授權的應該返回怎樣的響應和錯誤。
在官方網站中,你可以查看注釋文檔和可用參數。
那么這個 UnauthorizedError 來自哪里呢?
apiDoc 設置
有一些設置可以用 apiDoc 完成,這個 UnauthorizedError 就是我經常要用到的。
在 routes 目錄中創建一個名為 __apidoc.js
的文件,其中包含以下內容:
// -----------------------------------------------------------
// General apiDoc documentation blocks and old history blocks.
// -----------------------------------------------------------// -----------------------------------------------------------
// Current Success.
// -----------------------------------------------------------// -----------------------------------------------------------
// Current Errors.
// -----------------------------------------------------------// -----------------------------------------------------------
// Current Permissions.
// -----------------------------------------------------------
/*** @apiDefine UnauthorizedError* @apiVersion 1.0.0** @apiError Unauthorized Only authenticated users can access the endpoint.** @apiErrorExample Unauthorized response:* HTTP 401 Unauthorized* {* "message": "Invalid credentials"* }*/// -----------------------------------------------------------
// History.
// -----------------------------------------------------------
復制代碼
我還創建了另一個文件,也在 routes 目錄中,名為 apidoc.json
該文件包含以下內容(示例):
{"name": "Test API - This is my API","version": "1.0.0","description": "This is my very powerful API","title": "Test API - This is my API","url": "https://testapi.com"
}
復制代碼
生成文檔時,apiDoc 將會使用這兩個文件。
生成文檔
在為每個端點編寫注釋并配置好項目之后,我們需要配置一個任務來生成文檔。
我用 gulp 來做到這一切。安裝所需的依賴項:
npm i gulp gulp-apidoc --save-dev
復制代碼
然后在項目的根目錄中創建一個名為 gulpfile.js
的文件。如果它已經存在,只需添加與 apiDoc 相關的部分:
const gulp = require("gulp");
const apidoc = require("gulp-apidoc");gulp.task("apidoc", (done) => {apidoc({src: "./routes",dest: "../docs/apidoc"}, done);
});gulp.task("watch", () => {gulp.watch(["./routes/**"], ["apidoc"]);
});
復制代碼
你可以將那里的 “dest” 目錄更改為另一個更適合你的目錄。這就是你希望生成輸出的位置。
現在你需要做的就是運行:
gulp apidoc
復制代碼
之后,你只需要在上面 “dest” 中配置的目錄中打開 index.html 文件,就會看到類似這樣的內容):
其他開發人員也可以用 gulp 生成相同的內容,或者你??甚至可以通過 Nginx 為生成的目錄提供Web服務。
總結
在這本文中,我們了解了如何使用注釋來記錄 API,并使用 apiDoc 為它們生成 HTML 格式的文檔。
你是否還用了其他軟件來為你的 API 生成文檔,或者你是否以其他方式使用 apiDoc?請在下面評論中留言討論!