|
@@ -4,6 +4,7 @@
|
|
|
| 版本 | 日期 | 描述 | 作者 |
|
|
| 版本 | 日期 | 描述 | 作者 |
|
|
|
|------|------|------|------|
|
|
|------|------|------|------|
|
|
|
| 1.0 | 2026-01-03 | 初始版本,基于故事010.003修复经验总结 | James (Claude Code) |
|
|
| 1.0 | 2026-01-03 | 初始版本,基于故事010.003修复经验总结 | James (Claude Code) |
|
|
|
|
|
+| 1.1 | 2026-01-03 | 添加中线(kebab-case)路由规范 | James (Claude Code) |
|
|
|
|
|
|
|
|
## 概述
|
|
## 概述
|
|
|
|
|
|
|
@@ -19,6 +20,7 @@
|
|
|
2. **路径参数 `:param` 转换为 `[':param']` 索引**
|
|
2. **路径参数 `:param` 转换为 `[':param']` 索引**
|
|
|
3. **开头的 `/` 被移除**
|
|
3. **开头的 `/` 被移除**
|
|
|
4. **连续的 `/` 被压缩为单层嵌套**
|
|
4. **连续的 `/` 被压缩为单层嵌套**
|
|
|
|
|
+5. **中线 `-` (kebab-case) 必须使用方括号 `['path-with-hyphen']`**
|
|
|
|
|
|
|
|
## 调用方式详解
|
|
## 调用方式详解
|
|
|
|
|
|
|
@@ -105,6 +107,55 @@ const response = await client.admin.users[':id'].$get({ // ✅ 嵌套调用
|
|
|
});
|
|
});
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
+### 4. 路由带中线(kebab-case)
|
|
|
|
|
+
|
|
|
|
|
+**重要**: JavaScript中带连字符的属性名无法用点号访问,必须使用方括号表示法。
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+// 路由定义
|
|
|
|
|
+const route = createRoute({
|
|
|
|
|
+ method: 'get',
|
|
|
|
|
+ path: '/admin-users', // 中线路径
|
|
|
|
|
+ // ...
|
|
|
|
|
+});
|
|
|
|
|
+app.openapi(route, handler);
|
|
|
|
|
+
|
|
|
|
|
+// ❌ 错误:点号访问中线路径会报语法错误
|
|
|
|
|
+const response = await client.admin-users.$get();
|
|
|
|
|
+
|
|
|
|
|
+// ✅ 正确:使用方括号表示法
|
|
|
|
|
+const response = await client['admin-users'].$get();
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+// 路由定义 - 中线+参数
|
|
|
|
|
+const route = createRoute({
|
|
|
|
|
+ method: 'put',
|
|
|
|
|
+ path: '/unified-advertisements/:id',
|
|
|
|
|
+ // ...
|
|
|
|
|
+});
|
|
|
|
|
+app.openapi(route, handler);
|
|
|
|
|
+
|
|
|
|
|
+// ✅ 正确:方括号 + 嵌套参数
|
|
|
|
|
+const response = await client['unified-advertisements'][':id'].$put({
|
|
|
|
|
+ param: { id: 123 },
|
|
|
|
|
+ json: updateData
|
|
|
|
|
+});
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+// 路由定义 - 嵌套+中线
|
|
|
|
|
+const route = createRoute({
|
|
|
|
|
+ method: 'get',
|
|
|
|
|
+ path: '/admin/unified-advertisement-types',
|
|
|
|
|
+ // ...
|
|
|
|
|
+});
|
|
|
|
|
+app.openapi(route, handler);
|
|
|
|
|
+
|
|
|
|
|
+// ✅ 正确:嵌套对象 + 方括号
|
|
|
|
|
+const response = await client.admin['unified-advertisement-types'].$get();
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
## 常见错误 ❌
|
|
## 常见错误 ❌
|
|
|
|
|
|
|
|
### 错误1: 使用完整路径字符串
|
|
### 错误1: 使用完整路径字符串
|
|
@@ -162,6 +213,24 @@ const response = await client.admin.users.:id.$get();
|
|
|
const response = await client.admin.users[':id'].$get();
|
|
const response = await client.admin.users[':id'].$get();
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
+### 错误5: 中线路径使用点号访问
|
|
|
|
|
+
|
|
|
|
|
+```typescript
|
|
|
|
|
+// 路由定义: path: '/admin-users' 或 path: '/unified-advertisements'
|
|
|
|
|
+
|
|
|
|
|
+// ❌ 错误:JavaScript不允许用点号访问带连字符的属性
|
|
|
|
|
+const response = await client.admin-users.$get(); // 语法错误
|
|
|
|
|
+const response = await client['unified-advertisements'].$get(); // ✅ 正确:必须用方括号
|
|
|
|
|
+
|
|
|
|
|
+// ❌ 错误:混合使用点号和方括号
|
|
|
|
|
+const response = await client.admin['unified-advertisements'].$get(); // 如果路由是 /admin/unified-advertisements
|
|
|
|
|
+
|
|
|
|
|
+// ✅ 正确:全部使用方括号访问中线路径
|
|
|
|
|
+const response = await client['admin-users'].$get();
|
|
|
|
|
+const response = await client['unified-advertisements'][':id'].$put();
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
## 后端模块开发规范关联
|
|
## 后端模块开发规范关联
|
|
|
|
|
|
|
|
### 路由定义规范
|
|
### 路由定义规范
|
|
@@ -223,6 +292,9 @@ const response = await adminClient[':id'].$put({
|
|
|
| `path: '/:id'` | `.route('/api/v1/users', routes)` | `client[':id'].$get()` |
|
|
| `path: '/:id'` | `.route('/api/v1/users', routes)` | `client[':id'].$get()` |
|
|
|
| `path: '/users/:id'` | `.route('/api/v1/users', routes)` | `client.users[':id'].$get()` |
|
|
| `path: '/users/:id'` | `.route('/api/v1/users', routes)` | `client.users[':id'].$get()` |
|
|
|
| `path: '/admin/users/:id'` | `.route('/api/v1/admin', routes)` | `client.admin.users[':id'].$get()` |
|
|
| `path: '/admin/users/:id'` | `.route('/api/v1/admin', routes)` | `client.admin.users[':id'].$get()` |
|
|
|
|
|
+| `path: '/admin-users'` | `.route('/api/v1', routes)` | `client['admin-users'].$get()` |
|
|
|
|
|
+| `path: '/unified-advertisements/:id'` | `.route('/api/v1/admin', routes)` | `client['unified-advertisements'][':id'].$get()` |
|
|
|
|
|
+| `path: '/admin/ad-types'` | `.route('/api/v1/admin', routes)` | `client.admin['ad-types'].$get()` |
|
|
|
|
|
|
|
|
## 调用技巧
|
|
## 调用技巧
|
|
|
|
|
|
|
@@ -276,6 +348,9 @@ await client.$get() // path: '/' → .$get()
|
|
|
| `/users` | `.users.$get()`, `.users.$post()`, etc. |
|
|
| `/users` | `.users.$get()`, `.users.$post()`, etc. |
|
|
|
| `/users/:id` | `.users[':id'].$get()`, `.users[':id'].$put()`, etc. |
|
|
| `/users/:id` | `.users[':id'].$get()`, `.users[':id'].$put()`, etc. |
|
|
|
| `/admin/users/:id` | `.admin.users[':id'].$get()`, etc. |
|
|
| `/admin/users/:id` | `.admin.users[':id'].$get()`, etc. |
|
|
|
|
|
+| `/admin-users` | `['admin-users'].$get()`, etc. |
|
|
|
|
|
+| `/unified-advertisements/:id` | `['unified-advertisements'][':id'].$get()`, etc. |
|
|
|
|
|
+| `/admin/ad-types` | `.admin['ad-types'].$get()`, etc. |
|
|
|
|
|
|
|
|
### 核心原则
|
|
### 核心原则
|
|
|
|
|
|
|
@@ -283,6 +358,7 @@ await client.$get() // path: '/' → .$get()
|
|
|
2. **Server注册时添加前缀**:`.route('/api/v1/xxx', routes)`
|
|
2. **Server注册时添加前缀**:`.route('/api/v1/xxx', routes)`
|
|
|
3. **测试时映射路径结构**:`/` → `.$method()`, `/:id` → `[':id'].$method()`
|
|
3. **测试时映射路径结构**:`/` → `.$method()`, `/:id` → `[':id'].$method()`
|
|
|
4. **嵌套路径反映为嵌套对象**:`/admin/users/:id` → `.admin.users[':id'].$method()`
|
|
4. **嵌套路径反映为嵌套对象**:`/admin/users/:id` → `.admin.users[':id'].$method()`
|
|
|
|
|
+5. **中线路径必须用方括号**:`/admin-users` → `['admin-users'].$method()`
|
|
|
|
|
|
|
|
## 相关文档
|
|
## 相关文档
|
|
|
|
|
|