快速开始
欢迎使用 api-morph!本指南将通过一个完整的示例,带您逐步体验 api-morph 的强大功能。
前置准备工作
在开始之前,我们需要创建一个新的项目并配置好基本的开发环境。
1. 创建 package.json
首先创建项目目录并初始化 package.json:
mkdir my-api-project
cd my-api-project
创建 package.json
文件:
{
"name": "my-api-project",
"type": "module",
"scripts": {
"dev": "tsx watch index.ts"
}
}
2. 创建 tsconfig.json
创建 TypeScript 配置文件 tsconfig.json
:
{
"compilerOptions": {
"target": "ESNext",
"lib": ["ESNext"],
"moduleDetection": "force",
"module": "ESNext",
"moduleResolution": "bundler",
"types": ["node"],
"strict": true,
"skipLibCheck": true
},
"include": ["**/*.ts"]
}
3. 安装依赖
安装核心依赖:
pnpm add api-morph express zod
npm install api-morph express zod
yarn add api-morph express zod
安装开发依赖:
pnpm add -D @types/express @types/node typescript tsx
npm install -D @types/express @types/node typescript tsx
yarn add -D @types/express @types/node typescript tsx
第一步:搭建基本的 Express 应用
让我们先创建一个基本的 Express 应用框架。
创建 index.ts
文件:
import express from "express";
const app = express();
app.use(express.json());
const port = 3000;
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
第二步:定义 Zod Schema
接下来,我们创建必要的 Zod schema 来定义数据结构。创建 schema.ts
文件:
import { z } from "zod/v4";
export const UserIdDto = z.object({
id: z.string().meta({ description: "用户ID" }),
});
export const UpdateUserDto = z.object({
email: z.email().meta({
description: "用户邮箱地址",
examples: ["john.doe@example.com"],
}),
username: z
.string()
.min(3)
.max(50)
.meta({
description: "用户名",
examples: ["John Doe"],
}),
});
export const UpdateUserVo = z.object({
id: z.string().meta({ description: "用户ID" }),
email: z.email().meta({
description: "用户邮箱地址",
examples: ["john.doe@example.com"],
}),
username: z
.string()
.min(3)
.max(50)
.meta({
description: "用户名",
examples: ["John Doe"],
}),
});
这些 schema 定义了:
UserIdDto
:用于验证路径参数中的用户IDUpdateUserDto
:用于验证更新用户的请求体数据UpdateUserVo
:定义更新用户的响应数据结构
TIP
api-morph 仅支持 Zod v4 版本,因为只有 Zod v4 才支持生成 JSON Schema。请确保从 zod/v4
导入,而不是直接从 zod
导入。
第三步:定义 Express 路由
现在让我们在 index.ts
中添加一个获取用户信息的 API 路由:
import express from "express";
const app = express();
app.use(express.json());
app.put("/api/users/:id", (req, res) => {
const { id } = req.params;
const { email, username } = req.body;
res.json({
id,
email,
username,
});
});
const port = 3000;
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
第四步:定义基本路由信息
现在我们为路由添加 JSDoc 注释,包含 summary、description 和 tags:
import express from "express";
const app = express();
app.use(express.json());
/**
* @summary 更新用户信息
* @description 更新指定用户的个人信息
* @tags users
*/
app.put("/api/users/:id", (req, res) => {
const { id } = req.params;
const { email, username } = req.body;
res.json({
id,
email,
username,
});
});
const port = 3000;
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
JSDoc 注释说明:
@summary
:API 的简短描述@description
:API 的详细描述@tags
:API 分组标签,用于在文档中分类
第五步:通过中间件定义请求参数
现在我们引入 api-morph 的验证中间件来处理请求参数:
import express from "express";
import { validateRequest } from "api-morph/express";
import { UpdateUserDto, UserIdDto } from "./schema";
const app = express();
app.use(express.json());
/**
* @summary 更新用户信息
* @description 更新指定用户的个人信息
* @tags users
*/
app.put("/api/users/:id", (req, res) => {
app.put(
"/api/users/:id",
validateRequest({ params: UserIdDto, body: UpdateUserDto }),
(req, res) => {
const { id } = req.params;
const { email, username } = req.body;
res.json({
id,
email,
username,
});
},
);
const port = 3000;
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
这一步发生了什么?
通过集成 validateRequest
中间件,我们可以利用 Zod 对请求参数进行校验,这在真实的后端项目中几乎是必须的步骤。如果你不使用 api-morph,也会通过其他的方式实现这个功能。
api-morph 的核心理念是尽可能利用已有的代码,分析它,然后自动推断出必要的信息。 当你使用 validateRequest
后,api-morph 会分析它然后自动生成对应的请求参数文档。
具体来说:
- 自动验证路径参数:
params: UserIdDto
会验证 URL 中的:id
参数 - 自动验证请求体:
body: UpdateUserDto
会验证 POST/PUT 请求的 JSON 数据 - 自动生成文档:api-morph 会读取这些 Zod schema,并在 OpenAPI 文档中生成对应的参数说明
- 错误处理:如果验证失败,中间件会自动返回 400 错误响应
这样,你的业务代码既有了类型安全保障,又自动生成了准确的 API 文档,一举两得!
第六步:定义响应
现在我们在 JSDoc 注释中添加响应定义:
import express from "express";
import { validateRequest } from "api-morph/express";
import { UpdateUserDto, UserIdDto } from "./schema";
import { UpdateUserDto, UpdateUserVo, UserIdDto } from "./schema";
const app = express();
app.use(express.json());
/**
* @summary 更新用户信息
* @description 更新指定用户的个人信息
* @tags users
* @response 200 {@link UpdateUserVo} 更新用户信息成功
*/
app.put(
"/api/users/:id",
validateRequest({ params: UserIdDto, body: UpdateUserDto }),
(req, res) => {
const { id } = req.params;
const { email, username } = req.body;
res.json({
id,
email,
username,
});
},
);
const port = 3000;
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
@response
注释说明:
200
:HTTP 状态码{@link UpdateUserVo}
:引用我们定义的响应 schema更新用户信息成功
:响应描述
TIP
{@link}
是合法的 JSDoc 语法,用于创建对其他类型或变量的引用。api-morph 会解析这些链接并自动找到对应的 Zod schema 定义,然后在 OpenAPI 文档中生成完整的类型信息。
第七步:生成 OpenAPI 并在 Express 中提供服务
最后,我们添加生成和提供 OpenAPI 文档的功能:
import {
generateDocument,
generateSwaggerUI,
getSwaggerUIAssetInfo,
validateRequest,
} from "api-morph";
import { validateRequest } from "api-morph/express";
import express from "express";
import { UpdateUserDto, UpdateUserVo, UserIdDto } from "./schema";
const app = express();
app.use(express.json());
// 提供 Swagger UI 需要的静态资源
app.use(express.static(getSwaggerUIAssetInfo().assetPath));
/**
* @summary 更新用户信息
* @description 更新指定用户的个人信息
* @tags users
* @response 200 {@link UpdateUserVo} 更新用户信息成功
*/
app.put(
"/api/users/:id",
validateRequest({ params: UserIdDto, body: UpdateUserDto }),
(req, res) => {
const { id } = req.params;
const { email, username } = req.body;
res.json({
id,
email,
username,
});
},
);
// 生成 OpenAPI 文档
const openapi = await generateDocument(
{
info: {
version: "1.0.0",
title: "用户管理 API",
description: "这是一个用户管理 API 的文档示例",
},
},
);
// 提供 OpenAPI JSON 文档
app.get("/openapi.json", (req, res) => {
res.json(openapi);
});
// 提供 Swagger UI 界面
app.get("/swagger-ui", (req, res) => {
res.send(
generateSwaggerUI({
url: "/openapi.json",
}),
);
});
const port = 3000;
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
console.log(`访问 http://localhost:${port}/swagger-ui 查看 API 文档`);
});
运行和测试
现在启动应用:
npm run dev
你可以:
- 测试 API:使用 curl 或 Postman 测试
PUT /api/users/:id
接口 - 查看文档:访问
http://localhost:3000/swagger-ui
查看生成的 API 文档 - 获取 OpenAPI JSON:访问
http://localhost:3000/openapi.json
获取原始的 OpenAPI 规范
完整的文件结构
最终你的项目结构应该是这样的:
your-project/
├── index.ts # 主应用文件
├── schema.ts # Zod schema 定义
├── package.json # 项目配置
└── tsconfig.json # TypeScript 配置
下一步
现在你已经掌握了 api-morph 的基本用法!你可以:
- 添加更多的路由和 schema
- 探索更多的 JSDoc 标签功能
- 自定义 OpenAPI 文档的样式和配置
- 集成到现有的 Express 项目中
查看我们的其他指南了解更多高级功能!