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

翻译: 疯狂的技术宅

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

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

转载于:https://juejin.im/post/5cef97cff265da1bc14b0d3e

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/275052.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

海浪 shader_海浪下的发现

海浪 shaderI’ve been playing Subnautica for over 25 hours now, and likely have at least that many more to go. The game puts you in the shoes of a crew member on the Aurora, a spaceship that suffers a catastrophic incident and plummets to the largely ocean…

最后一天,特邀小姐姐配音拉票,今日可投28票

1源码共读大家好,我是若川。最后一天,特邀小姐姐配音拉票,超级好听。众所周知。从8月份开始,我组织了源码共读活动,至今已经有5个月了,每周一期,进行到了第18期。每周坚持写源码解读文章&#x…

NET中使用Memcached的相关资源整理

本文转自:http://www.cnblogs.com/dudu/archive/2009/07/19/1526407.html Memcached官方站点:http://www.danga.com/memcached / Memcached Win32 1.2.6下载:http://code.jellycan.com/memcached/ 安装帮助:Windows下的.NET Memca…

FFMPEG 视频图像解封装解码

FFMPEG4.0 音频解码解封装FFMPEG 音频封装编码 下面的函数方法基于最新的FFMPEG 4.0(4.X):本文讲是如何从一个视频文件中提取出其中的图像数据,并将图像数据保存到文件中。 解码解封装的过程与音频差不多,具体如下&…

对数据可视化的理解_使数据可视化更容易理解

对数据可视化的理解Data is weaving its way into almost all aspects of our lives since the past decade. Our ability to store more information in smaller and smaller spaces has encouraged us to make sure we leave no information out. The ease of collecting inf…

面试官:项目中常用的 .env 文件原理是什么?如何实现?

1. 前言大家好,我是若川。持续组织了5个月源码共读活动,感兴趣的可以点此加我微信 ruochuan12 参与,每周大家一起学习200行左右的源码,共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。本文仓库 h…

语言分类,我接触和我想学习的

本文信息和数据出自hyperpolyglot,将当前主流编程语言分为11个大类,分别为:解释型(PHP,Perl,Python,Ruby,Tcl,Lua,JavaScript,Io)、操作系统自动化型(POSIX Shell,AppleScript,PowerShell)、C风格(C,Objective C,Java,C#)、Pascal风格(Pascal…

梯度下降法和随机梯度下降法

1. 梯度 在微积分里面,对多元函数的参数求∂偏导数,把求得的各个参数的偏导数以向量的形式写出来,就是梯度。比如函数f(x,y), 分别对x,y求偏导数,求得的梯度向量就是(∂f/∂x, ∂f/∂y)T,简称grad f(x,y)或者▽f(x,y)。对于在点(x…

一张图看程序媛阿源的2021个人年度流水账

大家好,我是若川。持续组织了5个月源码共读活动,感兴趣的可以点此加我微信 ruochuan12 参与,每周大家一起学习200行左右的源码,共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。本文来自读者阿源小…

案例研究:设计与方法_如何进行1小时的重新设计(案例研究)

案例研究:设计与方法速度设计简介 (Intro to Speed Designing) I’ve been an advocate of speed redesigning technique for a while. The idea is simple — decrease the hand-eye lag and make super quick decisions, seemingly without thinking. The logic behind it is…

图文并茂重新认识下递归

大家好,我是若川。持续组织了5个月源码共读活动,感兴趣的可以点此加我微信 ruochuan12 参与,每周大家一起学习200行左右的源码,共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。对于大部分前端(包…

《C和指针》读书笔记

看过了经典的K&R C,又看了这本Pointers on C,温习了C语言的基本语法。 在重温过程中,感觉需要重点把握的知识是指针、结构和动态内存分配。 这对今后的算法和操作系统方面的研究学习很有帮助。 3.2.3 声明指针int* b, c, d;本以为这条语句…

FPGA设计者的5项基本功

记得《佟林传》里,佟林练的基本功是“绕大树、解皮绳”,然后才练成了什么“鬼影随行、柳叶绵丝掌”。 在我看来,成为一名说得过去的FPGA设计者,需要练好5项基本功:仿真、综合、时序分析、调试、验证。 需要强调的一点是…

unity 全息交互ui_UI向3D投影全息界面的连续发展

unity 全息交互uiThe user interface has been natural in its evolution and strategically heading towards the 3D-projection holographic interface (3D-PHI) era.用户界面在其发展过程中一直很自然,并且在战略上正朝着3D投影全息界面( 3D-PHI )时代迈进。 Si…

开发工具 快捷键整理

快捷键大全 JAVA 开发工具 MyEclipse -------------------------------------MyEclipse 快捷键1(CTRL)-------------------------------------Ctrl1 快速修复CtrlD: 删除当前行 CtrlQ 定位到最后编辑的地方 CtrlL 定位在某行 CtrlO 快速显示 OutLine CtrlT 快速显示当前类…

前端构建新世代,Esbuild 原来还能这么玩!

大家好,我是若川。持续组织了5个月源码共读活动,感兴趣的可以点此加我微信 ruochuan12 参与,每周大家一起学习200行左右的源码,共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。今天分享一篇esbui…

大三下学期十四周总结

在小组的学习方面,这周主要是对微信小程序的学习。对JSON格式请求在Spring boot与小程序之间的交互有了一些了解。对微信的接口wx.request、wx.uploadFile、wx.chooseImage的接口的使用。微信开发后台传过来的响应数据如果不是标准的json格式,需要在小程…

平面设计师和ui设计师_平面设计师为什么要享受所有乐趣?

平面设计师和ui设计师Graphic designers are pretty cool. We have to admit that. Be it their dressing style, their attitude and most importantly their enviable gadgets. Large Mac monitor, wacom tablet, drawing sets, swatchbooks , iPad pro with pencil, humungo…

转:Xcode下的GDB调试命令

Xcode的调试器为用户提供了一个GDB的图形化界面,GDB是GNU组织的开放源代码调试器。您可以在Xcode的图形界面里做任何事情;但是,如果您需要您可以在命令行里使用GDB的命令,且gdb可以在终端运行,也可以在Xcode下的控制台…

web表单设计:点石成金_设计复杂的用户表单:12个UX最佳实践

web表单设计:点石成金It’s been a few years that I’ve been taking interest in designing complex user forms, where a lot of information is requested from users. Here are a few industries where you regularly find such flows:几年来,我一直对设计复杂…