API 文档
规则
- OpenAPI 3.1 规范作为唯一权威来源 — 从代码生成,而非手动编写
- Zod 架构转 OpenAPI:使用
zod-openapi 或 @asteasolutions/zod-to-openapi — 定义一次,验证和文档同步
- 交互式文档:Scalar(现代、快速)或 Swagger UI — 在
/docs 或 /api-docs 提供服务
- 每个端点必须包含:摘要、描述、请求体架构、所有响应码及示例
- 每个端点必须提供示例请求/响应 — 使用真实数据,而非
"string" 占位符
- 版本策略:对破坏性变更使用 URL 路径(
/api/v1/、/api/v2/)— 比头部版本管理更简单
- 错误响应:以一致的格式记录所有错误形状 —
{ error: string, code: string, details?: object }
- 身份验证:在安全方案部分记录认证方案(Bearer 令牌、API 密钥)
- 按资源分组端点:
/users、/products、/orders — 在文档 UI 中使用标签进行分组
模式
import { z } from "zod";
import { extendZodWithOpenApi } from "@asteasolutions/zod-to-openapi";
extendZodWithOpenApi(z);
const UserSchema = z.object({
id: z.string().uuid().openapi({ example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890" }),
name: z.string().openapi({ example: "Jane Smith" }),
email: z.string().email().openapi({ example: "[email protected]" }),
}).openapi("User");
const CreateUserSchema = UserSchema.omit({ id: true }).openapi("CreateUser");
registry.registerPath({
method: "post",
path: "/api/v1/users",
summary: "创建用户",
request: { body: { content: { "application/json": { schema: CreateUserSchema } } } },
responses: {
201: { description: "用户创建成功", content: { "application/json": { schema: UserSchema } } },
400: { description: "校验错误" },
},
});
避免
- 手动编写 OpenAPI YAML — 从 Zod 架构或路由定义生成
- 缺少错误响应文档 — 记录 400、401、403、404、500
- 使用
"string" 或 0 等通用示例 — 使用能展示真实数据形状的现实值
- 文档与实现脱节 — 从验证所用的同一架构生成规范