Files
d8d-vite-starter/.roo/rules/07-openapi.md
D8D Developer b9a3c991d0 update
2025-06-27 01:56:30 +00:00

272 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Hono OpenAPI规范
## 常见不规范问题
1. **路径参数问题**:
- ❌ 使用冒号定义路径参数: `/:id`
- ✅ 必须使用花括号: `/{id}`
2. **参数Schema缺失**:
- ❌ 未定义params Schema
- ✅ 必须定义并添加OpenAPI元数据
3. **参数获取方式**:
- ❌ 使用`c.req.param()`
- ✅ 必须使用`c.req.valid('param')`
4. **URL参数类型转换**:
- ❌ 直接使用z.number()验证URL查询参数
- ✅ 必须使用z.coerce.number()自动转换字符串参数
5. **OpenAPI元数据**:
- ❌ 路径参数缺少OpenAPI描述
- ✅ 必须包含example和description
6. **api响应**:
- ❌ 200响应码缺少
- ✅ 200也必须写c.json(result, 200)
7. **认证中间件**:
- ❌ security: [{ Bearer: [] }],
- ✅ middleware: [authMiddleware],
8. **子路由路径**:
- ❌ path: '/users',
- ✅ path: '/',
- ❌ path: '/users/{id}',
- ✅ path: '/{id}',
## 核心规范
### 1. 路由定义
### 2. 查询参数处理
- **URL参数类型**:
- URL查询参数总是以字符串形式传递
- 必须正确处理字符串到其他类型的转换
- **数字参数处理**:
```typescript
// 错误方式 - 直接使用z.number()
z.number().int().positive() // 无法处理字符串参数
// 正确方式 - 使用z.coerce.number()
z.coerce.number().int().positive() // 自动转换字符串参数
```
- **布尔参数处理**:
```typescript
// 错误方式 - 直接使用z.boolean()
z.boolean() // 无法处理字符串参数
// 正确方式 - 使用z.coerce.boolean()
z.coerce.boolean() // 自动转换字符串参数
```
- **路径参数**:
- 必须使用花括号 `{}` 定义 (例: `/{id}`)
- 必须定义 params Schema 并添加 OpenAPI 元数据:
```typescript
const GetParams = z.object({
id: z.string().openapi({
param: { name: 'id', in: 'path' },
example: '1',
description: '资源ID'
})
});
```
- 路由定义中必须包含 params 定义:
```typescript
request: { params: GetParams }
```
- 必须使用 `c.req.valid('param')` 获取路径参数
- **请求定义**:
```typescript
request: {
body: {
content: {
'application/json': { schema: YourZodSchema }
}
}
}
```
- **响应定义**:
```typescript
responses: {
200: {
description: '成功响应描述',
content: { 'application/json': { schema: SuccessSchema } }
},
400: {
description: '客户端错误',
content: { 'application/json': { schema: ErrorSchema } }
},
500: {
description: '服务器错误',
content: { 'application/json': { schema: ErrorSchema } }
}
}
```
列表响应定义示例
```typescript
// 列表响应Schema, 响应时data应统一用实体中定义的schema
import { RackInfoSchema } from '@/server/modules/racks/rack-info.entity';
const RackListResponse = z.object({
data: z.array(RackInfoSchema),
pagination: z.object({
total: z.number().openapi({
example: 100,
description: '总记录数'
}),
current: z.number().openapi({
example: 1,
description: '当前页码'
}),
pageSize: z.number().openapi({
example: 10,
description: '每页数量'
})
})
});
```
- **路由示例**:
```typescript
const routeDef = createRoute({
method: 'post',
path: '/',
middleware: [authMiddleware],
request: {
body: {
content: { 'application/json': { schema: CreateSchema } }
}
},
responses: {
200: { ... },
400: { ... },
500: { ... }
}
});
```
### 2. 错误处理
- 错误响应必须使用统一格式: `{ code: number, message: string }`
- 必须与OpenAPI定义完全一致
- 处理示例:
```typescript
try {
// 业务逻辑
} catch (error) {
return c.json({ code: 500, message: '操作失败' }, 500);
}
```
### 3. dataSource引入
- 示例:
```typescript
import { AppDataSource } from '@/server/data-source';
```
### 4. service初始化
- 示例:
```typescript
import { WorkspaceService } from '@/server/modules/workspaces/workspace.service';
const workspaceService = new WorkspaceService(AppDataSource);
### 5. 用户context获取
- 示例:
```typescript
const user = c.get('user');
```
- 注意: 确保 `c.get('user')` 已经在 `authMiddleware` 中设置
### 6. AuthContext引用
- 示例:
```typescript
import { AuthContext } from '@/server/types/context';
```
### 7. createRoute, OpenAPIHono 引入
- 示例:
```typescript
import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
```
### 8. ErrorSchema 引入
- 示例:
```typescript
import { ErrorSchema } from '@/server/utils/errorHandler';
```
## 进阶规范
### 1. 路由聚合
当多个相关路由需要组合时:
1. **文件结构**:
- 拆分为独立文件 (`create.ts`, `list.ts` 等)
- 创建 `index.ts` 聚合所有子路由
```
src/server/api/
├── [resource]/ # 资源路由目录
│ ├── [id]/ # 带ID的子路由
│ │ ├── get.ts # 获取单条
│ │ ├── put.ts # 更新单条
│ │ └── delete.ts # 删除单条
│ ├── get.ts # 列表查询
│ ├── post.ts # 创建资源
│ └── index.ts # 聚合导出
```
2. **实现**:
```typescript
import listRoute from './get';
import createRackRoute from './post';
import getByIdRoute from './[id]/get';
import updateRoute from './[id]/put';
import deleteRoute from './[id]/delete';
import { OpenAPIHono } from '@hono/zod-openapi';
const app = new OpenAPIHono()
.route('/', listRoute)
.route('/', createRackRoute)
.route('/', getByIdRoute)
.route('/', updateRoute)
.route('/', deleteRoute)
export default app;
```
3. **优势**:
- 保持模块化
- 简化维护
- 统一API入口
## 路由文件代码结构规范
+imports: 依赖导入
+serviceInit: 服务初始化
+paramsSchema: 路径参数定义
+responseSchema: 响应定义
+errorSchema: 错误定义
+routeDef: 路由定义
+app: 路由实例
## src/server/api.ts 统一引入
```ts
import authRoute from '@/server/api/auth/index'
const routes = api.route('/api/v1/auth', authRoute)
```
## 完整示例
```typescript
// 路由实例
const app = new OpenAPIHono<AuthContext>().openapi(routeDef, async (c) => {
try {
// 业务逻辑
return c.json(result, 200);
} catch (error) {
return c.json({
code: 500,
message: error instanceOf Error ? error.message : '操作失败'
}, 500);
}
});
export default app;
```