# API 开发规范 ## 文件结构 每个API模块必须包含以下文件: - `*.schema.ts` - 请求参数和数据结构定义 + TypeScript类型导出 - `*.response.ts` - 响应格式定义 + 响应类型导出 - `*.service.ts` - 业务逻辑实现(使用类型注解) - `*.controller.ts` - 路由和控制器(使用Schema验证) - `*.test.ts` - 测试用例(类型安全的测试数据) ## 开发流程 1. **Schema 定义** - 使用 TypeBox 定义请求参数和数据结构,导出TypeScript类型 2. **Response 定义** - 基于全局响应格式定义各种场景的响应,导出响应类型 3. **Service 实现** - 编写业务逻辑,使用类型注解确保类型安全 4. **Controller 实现** - 集成JWT认证、Schema验证、错误处理 5. **测试编写** - 使用类型安全的测试数据,覆盖正常、异常、边界场景 ## 必须遵循 ### 1. 认证与授权 ```typescript // 需要认证的接口必须使用 jwtAuthPlugin export const controller = new Elysia().use(jwtAuthPlugin).get('/protected-route', handler, options); ``` ### 2. 参数验证与类型使用 ```typescript // example.schema.ts - 定义Schema和导出类型 import { t, type Static } from 'elysia'; export const GetUserByUsernameSchema = t.Object({ username: t.String({ minLength: 2, maxLength: 50 }), }); // 导出TypeScript类型 export type GetUserByUsernameParams = Static; // example.service.ts - Service中使用类型 import type { GetUserByUsernameParams } from './example.schema'; export class ExampleService { async getUserByUsername(params: GetUserByUsernameParams): Promise { const { username } = params; // 类型安全 // 业务逻辑... } } // example.controller.ts - Controller中使用Schema验证 export const controller = new Elysia().use(jwtAuthPlugin).get('/user/:username', handler, { params: GetUserByUsernameSchema, // 运行时验证 }); ``` **要求:** - ✅ 每个Schema必须导出对应的TypeScript类型 - ✅ Service方法必须使用类型注解 - ❌ 禁止行内定义任何参数Schema ### 3. 统一响应格式 ```typescript // 成功响应 return { code: ERROR_CODES.SUCCESS, message: '操作成功', data: result, }; // 错误响应 return { code: ERROR_CODES.BUSINESS_ERROR, message: '具体错误信息', data: null, }; ``` - 响应内容的类型需要在.response.ts中定义 ### 4. 错误处理 ```typescript try { const result = await service.method(); return successResponse(result); } catch (error) { Logger.error(new Error(`操作失败: ${error}`)); const errorMessage = error instanceof Error ? error.message : '未知错误'; if (errorMessage.includes('特定错误')) { set.status = 400; return errorResponse(ERROR_CODES.BUSINESS_ERROR, '业务错误消息'); } set.status = 500; return errorResponse(ERROR_CODES.INTERNAL_ERROR, '服务器内部错误'); } ``` ### 5. 文档配置 ```typescript { detail: { summary: '接口简要描述', description: '接口详细描述', tags: [tags.moduleName], security: [{ bearerAuth: [] }], // 需要认证时添加 }, response: PredefinedResponses, } ``` ### 6. 日志记录 ```typescript // 接口调用日志 Logger.info(`接口被调用,参数: ${param}, 用户: ${JSON.stringify(user)}`); // 成功日志 Logger.info(`操作成功,结果: ${result.id}`); // 错误日志 Logger.error(new Error(`操作失败,错误: ${error}`)); ``` ### 7. 必要的注释 1. 接口名称注释 ```typescript export const controller = new Elysia() .use(jwtAuthPlugin) /** * 根据用户名查询用户信息 * @route GET /api/sample/user/:username * @description 通过用户名查询用户的详细信息,需要JWT认证 * @param username 用户名,路径参数,长度2-50字符 * @returns 用户信息对象或错误响应 * @modification hotok 2025-06-29 初始实现 */ .get('/protected-route', handler, options); ``` ## 禁止事项 - ❌ 直接在 Controller 中写业务逻辑 - ❌ 不进行参数验证 - ❌ 返回非标准格式的响应 - ❌ 暴露敏感信息(如密码哈希) - ❌ 缺少错误处理和日志记录 - ❌ 不编写测试用例 ## 命名规范 - 文件名:`module.type.ts`(如:`user.controller.ts`) - Schema:`GetUserByIdSchema`、`CreateUserSchema` - Response:`GetUserSuccessResponse`、`UserErrorResponse` - Service 类:`UserService`、导出实例:`userService` - Controller:`userController` ## 测试要求 每个接口必须包含: - ✅ 正常流程测试 - ✅ 参数验证边界测试(最短、最长、无效格式) - ✅ 业务逻辑异常测试(不存在、权限不足等) - ✅ 认证相关测试(无Token、无效Token、过期Token) - ✅ 响应格式验证(状态码、code、message、data结构)