在 Node.js 中使用 Yaml 编写API文档
在文章《使用Node.js、MongoDB、Fastify 构建API服务》中介绍使用 Swagger 构建 API 文档,编写文档不是那么的顺手,本文介绍另一种编写 API 文档的方式,即使用 Yaml ,将API文档与其实现完全分开。
文章将继续在项目 restful-api 基础上进行迭代,首先先来简单了解一下 Yaml。
什么是 Yaml
YAML 是一种常用于数据序列化的文件格式,有很多项目使用 YAML 文件进行配置,常见的有 docker-compose
、ESLint
、Kubernetes
等等。最初代表 Yet Another Markup Language
,后来改为 YAML Ain't Markup Language
,以区别于真正的标记语言。
它类似于 XML 和 JSON 文件,但使用更简约的语法,即使在保持类似功能的同时也是如此。YAML 是 JSON 的超集(来源),每个有效的 JSON 文件也是一个有效的 YAML 文件。前面 Swagger 文档就是需要构建一个 JSON 数据,正好利用 YAML 的这个特性。
YAML 文件使用类似于 Python 的缩进系统来显示程序的结构,需要使用空格而不是制表符来创建缩进以避免混淆。
编写 Yaml
在项目目录 src/docs
中创建文件 api.yaml
,添加以下代码:
openapi: 3.0.1
info:
description: 这是一个关于咖啡种类的 API。
title: Coffee Restful API
version: 1.0.0
servers:
- description: Main server
url: http://localhost:8100/api/v1
paths:
/coffees:
get:
operationId: coffeesGET
responses:
"200":
content:
application/json:
schema:
items:
$ref: "#/components/schemas/Coffee"
type: array
x-content-type: application/json
description: 获取成功
description: 获取咖啡种类列表
summary: 获取所有的咖啡种类列表
tags:
- Coffees
post:
operationId: coffeesPOST
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/CoffeeRequest"
responses:
"200":
content:
application/json:
schema:
items:
$ref: "#/components/schemas/Coffee"
type: array
x-content-type: application/json
description: 创建成功
description: 增加新的咖啡种类
summary: 创建新的咖啡种类
tags:
- Coffees
/coffees/{id}:
get:
operationId: coffeesIdGET
parameters:
- description: 咖啡种类id
explode: false
in: path
name: id
required: true
schema:
type: string
style: simple
responses:
"200":
content:
application/json:
schema:
$ref: "#/components/schemas/Coffee"
description: 获取详情成功
description: 通过id获取咖啡种类详情
summary: 获取咖啡种类详情
tags:
- Coffees
delete:
operationId: coffeesIdDELETE
parameters:
- description: 咖啡种类id
explode: false
in: path
name: id
required: true
schema:
type: string
style: simple
responses:
"204":
description: 删除成功
description: 通过id删除咖啡种类详情
summary: 删除咖啡种类详情
tags:
- Coffees
put:
operationId: coffeesIdPUT
parameters:
- description: 咖啡种类id
explode: false
in: path
name: id
required: true
schema:
type: string
style: simple
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/CoffeeRequest"
responses:
"201":
content:
application/json:
schema:
$ref: "#/components/schemas/Coffee"
description: 更新成功
description: 通过id 更新咖啡种类详情
summary: 更新咖啡种类详情
tags:
- Coffees
components:
schemas:
Coffee:
example:
_id: id
title: title
ratio: ratio
cup: cup
description: description
properties:
_id:
maxLength: 24
minLength: 24
type: string
title:
type: string
ratio:
type: string
cup:
type: string
description:
type: string
type: object
CoffeeRequest:
example:
title: "Red Eye"
ratio: "1 shot of espresso"
cup: "8 oz. Coffee Mug"
description: description
properties:
title:
type: string
ratio:
type: string
cup:
type: string
description:
type: string
type: object
修改配置 src/config/swagger.js
,完整代码如下:
exports.options = {
routePrefix: "/api/v1/helper",
exposeRoute: true,
yaml: true,
mode: "static",
};
去掉路由中与文档相关的信息,修改文件 src/routes/index.js
,完整代码如下:
const coffeeController = require("../controllers/coffeeController");
const APIPATH = "/api/";
const VERSION = "v1";
const ENDPOINT = "/coffees";
const getFullPath = (method = "") => `${APIPATH}${VERSION}${ENDPOINT}${method}`;
const routes = [
{
method: "GET",
url: getFullPath(),
handler: coffeeController.getList,
},
{
method: "GET",
url: getFullPath("/:id"),
handler: coffeeController.get,
},
{
method: "POST",
url: getFullPath(),
handler: coffeeController.add,
},
{
method: "PUT",
url: getFullPath("/:id"),
handler: coffeeController.update,
},
{
method: "DELETE",
url: getFullPath("/:id"),
handler: coffeeController.delete,
},
];
module.exports = routes;
修改入口文件 src/index.js
,主要是修改 swagger 的部分,如下:
fastify.register(require("fastify-swagger"), {
...swagger.options,
specification: {
path: path.join(__dirname, "./docs", "api.yaml"),
postProcessor: function (swaggerObject) {
return swaggerObject;
},
},
});
运行后打开 API 文档路径,可以看到下面效果:
文章涉及的源代码地址: restful-api