在 Express 中即时生成文档
不久前,我决定为即将构建的一些 HTTP API 生成文档。这些 API 将在内部使用,所以我不想使用任何在线解决方案,例如API Blueprint、Apiary或Swagger。而且,从头开始设置这些东西……有点麻烦。此外,我希望将文档集成到代码中,避免为了编写文档而进行任何上下文切换。
我知道jsdoc
和esdoc
,它们都允许我们在注释中编写文档。但是,它们的作用是记录 JavaScript 代码,而不是 HTTP API。后来,我找到了一个工具swagger-jsdoc
,它可以从注释中生成 Swagger / OpenAPI 规范。这正是我想要的。
code
现在让我们看看
这只是一个简单的动物列表服务器,你也可以添加自己喜欢的动物。这概念相当新颖。
const express = require('express');
const bodyparser = require('body-parser');
const app = express();
app.use(bodyparser.json({
strict: false,
}));
const animals = [
'panda', 'racoon', 'python',
];
app.get('/list', (req, res) => {
return res.json(req.query.sort === 'yes' ? Array.from(animals).sort() : animals); // why is .sort inplace 😠
});
app.post('/add', (req, res) => {
animals.push(...req.body.animals);
return res.json({
message: 'Added',
});
});
app.listen(3000, () => {
console.log('Server started at port 3000');
});
swagger-jsdoc
需要注释来遵循OpenAPI 规范,这非常直观。
为路线添加文档注释/list
。
/**
* @swagger
* /list:
* get:
* summary: List all the animals
* description: Returns a list of all the animals, optionally sorted
* tags:
* - animals
* parameters:
* - in: query
* name: sort
* type: string
* required: false
* enum:
* - yes
* - no
* responses:
* 200:
* description: List of animals
* schema:
* type: object
* properties:
* animals:
* type: array
* description: all the animals
* items:
* type: string
*/
app.get('/list', (req, res) => {
// ...
});
第一行@swagger
用于swagger-jsdoc
标识此注释块为 Swagger (OpenAPI) 规范。接下来的几行定义了路径、方法、简要概述和描述。tags
用于对 API 进行分组。
接下来将介绍预期参数query
和。我们的API 需要一个可选的查询参数,用于在发送之前决定动物列表是否需要排序。path
/list
sort
然后我们定义响应。首先是状态,然后是一些描述,最后是响应的模式。这里我们返回的是 JSON。不过,记录其他内容类型也很容易。
我们将对请求做同样的事情/add
。
/**
* @swagger
* /add:
* post:
* summary: Add more animal
* description: Add animals to the list
* tags:
* - animals
* requestBody:
* content:
* application/json:
* schema:
* type: object
* properties:
* animals:
* type: array
* items:
* type: string
* responses:
* 200:
* description: Adds the animals in body
* schema:
* type: object
* properties:
* message:
* type: string
* default: 'Added'
*/
app.post('/add', (req, res) => {
// ...
});
现在我们已经准备好注释,我们将连接swagger-jsdoc
模块。
// ... other modules
const swaggerJSDoc = require('swagger-jsdoc');
const app = express();
app.use(bodyparser.json({
strict: false,
}));
const animals = [
'panda', 'racoon', 'python',
];
// -- setup up swagger-jsdoc --
const swaggerDefinition = {
info: {
title: 'Animals',
version: '1.0.0',
description: 'All things animlas',
},
host: 'localhost:3000',
basePath: '/',
};
const options = {
swaggerDefinition,
apis: [path.resolve(__dirname, 'server.js')],
};
const swaggerSpec = swaggerJSDoc(options);
// -- routes for docs and generated swagger spec --
app.get('/swagger.json', (req, res) => {
res.setHeader('Content-Type', 'application/json');
res.send(swaggerSpec);
});
// other routes
这将在 上提供 Swagger 规范/swagger.json
。剩下要做的就是以更人性化的方式呈现此规范。为此,我选择了ReDoc 。它的设置很简单。
包含 HTML 文件
<!DOCTYPE html>
<html>
<head>
<title>Quizizz Docs</title>
<!-- needed for adaptive design -->
<meta charset="utf-8"/>
<link rel="shortcut icon" type="image/x-icon" href="https://quizizz.com/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
<!--
ReDoc doesn't change outer page styles
-->
<style>
body {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<!-- we provide is specification here -->
<redoc spec-url='http://localhost:3000/swagger.json' expand-responses="all"></redoc>
<script src="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"> </script>
</body>
</html>
我们已经将 设置http://localhost:3000/docs/swagger.json
为 JSON 规范服务器的位置。让我们也设置一个路由来提供此 HTML 服务。
app.get('/docs', (req, res) => {
res.sendFile(path.join(__dirname, 'redoc.html'));
});
结果,
鏂囩珷鏉ユ簮锛�https://dev.to/akshendra/generate-documentation-on-the-fly-in-express-2652OpenAPI 拥有更多组件,
swagger-jsdoc
简化了流程。您可以为多次使用的模式/请求/响应编写定义,然后在文档中使用它们。查看组件部分 | Swagger和入门 | Swagger JSDoc,了解如何以 JavaScript 方式定义它们。代码可以在这里找到