Просмотр исходного кода

docs(standards): 补充createZodErrorResponse和路由响应Schema对应关系

- 4.3节添加完整的createRoute定义示例
- 说明400响应使用ZodErrorSchema(因为使用createZodErrorResponse)
- 说明其他错误(401, 404, 500)使用ErrorSchema
- 更新4.4节关键要点,包含响应Schema规范
- 更新检查清单,添加响应Schema检查项

🤖 Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
yourname 3 недель назад
Родитель
Сommit
a9589de9b7
1 измененных файлов с 84 добавлено и 5 удалено
  1. 84 5
      docs/architecture/backend-module-package-standards.md

+ 84 - 5
docs/architecture/backend-module-package-standards.md

@@ -309,7 +309,76 @@ export * from './channel-crud.routes';
 
 **重要**: 自定义路由(非CRUD路由)在返回响应前**必须使用 `parseWithAwait`** 验证和转换数据。
 
-**实际实现**:
+#### 使用 createRoute 定义路由
+
+**完整示例**:
+```typescript
+import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
+import { z } from '@hono/zod-openapi';
+import { parseWithAwait, createZodErrorResponse } from '@d8d/shared-utils';
+import { ErrorSchema, ZodErrorSchema } from '@d8d/shared-utils/schema/error';
+import { ChannelSchema, CreateChannelSchema } from '../schemas/channel.schema';
+
+// 定义路由(包含请求和响应Schema)
+const createChannelRoute = createRoute({
+  method: 'post',
+  path: '/create',
+  middleware: [authMiddleware],
+  request: {
+    body: {
+      content: {
+        'application/json': { schema: CreateChannelSchema }
+      }
+    }
+  },
+  responses: {
+    200: {
+      description: '创建成功',
+      content: {
+        'application/json': { schema: ChannelSchema }
+      }
+    },
+    // ✅ 400使用 ZodErrorSchema(因为使用 createZodErrorResponse)
+    400: {
+      description: '参数错误',
+      content: { 'application/json': { schema: ZodErrorSchema } }
+    },
+    // ✅ 其他错误使用 ErrorSchema
+    401: {
+      description: '认证失败',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    500: {
+      description: '服务器错误',
+      content: { 'application/json': { schema: ErrorSchema } }
+    }
+  }
+});
+
+// 实现路由处理函数
+channelCustomRoutes.openapi(createChannelRoute, async (c) => {
+  try {
+    const data = c.req.valid('json');
+    const channelService = new ChannelService(AppDataSource);
+    const result = await channelService.create(data);
+
+    // ✅ 必须:使用 parseWithAwait 验证和转换响应数据
+    const validatedResult = await parseWithAwait(ChannelSchema, result);
+    return c.json(validatedResult, 200);
+  } catch (error) {
+    if (error instanceof z.ZodError) {
+      // ✅ 推荐:使用 createZodErrorResponse 处理Zod验证错误
+      return c.json(createZodErrorResponse(error), 400);
+    }
+    return c.json({ code: 500, message: error.message }, 500);
+  }
+});
+```
+
+#### 不使用 createRoute 的简化写法
+
+如果路由不需要完整的 OpenAPI 文档定义,可以使用简化写法:
+
 ```typescript
 import { parseWithAwait, createZodErrorResponse } from '@d8d/shared-utils';
 import { z } from '@hono/zod-openapi';
@@ -335,7 +404,8 @@ channelCustomRoutes.get('/statistics/:id', async (c) => {
 });
 ```
 
-**数组响应处理**:
+#### 数组响应处理
+
 ```typescript
 // 处理数组数据
 const validatedData = await Promise.all(
@@ -344,10 +414,16 @@ const validatedData = await Promise.all(
 return c.json({ data: validatedData, total: result.total }, 200);
 ```
 
-**关键要点**:
-- **必须使用 `parseWithAwait`**: 所有自定义路由返回前必须使用 `parseWithAwait` 验证数据
+#### 关键要点
+
+**响应Schema定义**:
+- **400响应使用 `ZodErrorSchema`**: 因为使用 `createZodErrorResponse` 返回详细的验证错误
+- **其他错误使用 `ErrorSchema`**: 401, 404, 500 等使用简单的错误格式
+
+**代码实现**:
+- **必须使用 `parseWithAwait`**: 所有自定义路由返回前必须验证数据
 - **捕获 ZodError**: 在catch块中处理 `z.ZodError` 异常
-- **使用 `createZodErrorResponse`**: 提供统一的错误响应格式
+- **使用 `createZodErrorResponse`**: 提供统一的Zod错误响应格式
 - **数组使用 `Promise.all`**: 批量验证数组数据
 
 ### 4.4 关键要点
@@ -357,6 +433,8 @@ return c.json({ data: validatedData, total: result.total }, 200);
 - **路由聚合**: 分别定义自定义路由和CRUD路由,然后聚合
 - **不设置 `basePath`**: 在聚合路由时处理路径
 - **自定义路由必须使用 `parseWithAwait`**: 验证响应数据符合Schema定义
+- **400响应使用 `ZodErrorSchema`**: 因为使用 `createZodErrorResponse` 返回详细验证错误
+- **其他错误使用 `ErrorSchema`**: 401, 404, 500 等使用简单错误格式
 
 ## 5. Schema规范
 
@@ -741,6 +819,7 @@ override async create(data: Partial<Channel>, userId?: string | number): Promise
 - [ ] 路由使用 `OpenAPIHono` 和 `AuthContext`
 - [ ] 自定义路由使用 `parseWithAwait` 验证响应数据
 - [ ] 自定义路由使用 `createZodErrorResponse` 处理Zod错误
+- [ ] 路由400响应使用 `ZodErrorSchema`,其他错误使用 `ErrorSchema`
 - [ ] 测试数据工厂使用时间戳保证唯一性
 - [ ] vitest.config.ts 设置 `fileParallelism: false`
 - [ ] 类型检查通过