使用 apiDoc 为你的Node.js API 生成文档

翻译: 疯狂的技术宅html

原文:jonathas.com/documenting…前端

未经许可,禁止转载!node

当你为其余开发人员(前端,桌面,移动等)开发 API 时,须要生成一份风格良好的文档,以便他们知道可使用的内容和方式,这很是重要。git

为此,在Node.js项目中,我一直在使用apiDoc,由于它可以从源代码中的注释生成HTML文档。github

对于本文,我将使用我开发的 TODO List API 做为示例。你能够从这里克隆或下载它。typescript

路由和注释

在我关于使用 mocha 进行测试并使用 istanbul 进行代码覆盖测试的文章中,我在 TODO List API 中显示了 Task 端点的示例:npm

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 ​​的开发人员应该向每一个端点发送什么数据呢?json

到如今为止,他们除了去查看代码以外没有其余方法能够搞清楚,可是这些代码不该该被用做这个目的。gulp

有了 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?请在下面评论中留言讨论!

欢迎关注前端公众号:前端先锋,获取前端工程化实用工具包。

相关文章
相关标签/搜索