Explorar el Código

docs: 修正Hono RPC Client规范文档,前端使用rpcClient而非直接使用hc

根据UI包开发规范,前端UI包使用的是:
- @d8d/shared-ui-components/utils/hc 的 rpcClient
- 而非直接使用 @hono/rpc 的 hc

主要更新:
- 概述部分更新为正确的包路径
- 基本原理部分更新
- 章节5标题从"前端 RPC Client (hc) 使用"改为"前端 UI 包 RPC Client 使用"
- 添加UI包标准ClientManager模式示例
- 添加路由名称对应关系表
- 相关文档添加UI包开发规范链接

版本更新:1.2 → 1.3

🤖 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 hace 2 semanas
padre
commit
fbb7eaf38e
Se han modificado 1 ficheros con 46 adiciones y 29 borrados
  1. 46 29
      docs/architecture/hono-testing-testclient-standards.md

+ 46 - 29
docs/architecture/hono-testing-testclient-standards.md

@@ -6,22 +6,23 @@
 | 1.0 | 2026-01-03 | 初始版本,基于故事010.003修复经验总结 | James (Claude Code) |
 | 1.1 | 2026-01-03 | 添加中线(kebab-case)路由规范 | James (Claude Code) |
 | 1.2 | 2026-01-03 | 明确规范同样适用于前端RPC client (hc) | James (Claude Code) |
+| 1.3 | 2026-01-03 | 修正前端使用rpcClient而非直接使用hc | James (Claude Code) |
 
 ## 概述
 
 本文档定义了使用 Hono RPC 客户端时的正确调用方式,包括:
-- **测试环境**: `hono/testing` 的 `testClient` - 用于集成测试
-- **生产环境**: `@hono/rpc` 的 `hc` - 用于前端 RPC 调用
+- **测试环境**: `hono/testing` 的 `testClient` - 用于后端集成测试
+- **生产环境**: `@d8d/shared-ui-components/utils/hc` 的 `rpcClient` - 用于前端 UI 包 RPC 调用
 
 两者的路径映射规则完全一致,本文档的规范适用于所有 Hono RPC 客户端。
 
 ## 基本原理
 
-Hono RPC 客户端(包括 `testClient` 和 `hc`)会根据路由的路径结构自动生成类型安全的客户端对象。关键是理解路径到属性的映射规则。
+Hono RPC 客户端(包括 `testClient` 和 `rpcClient`)会根据路由的路径结构自动生成类型安全的客户端对象。关键是理解路径到属性的映射规则。
 
 **所有 Hono RPC 客户端共享相同的路径映射规则**,无论是:
 - 后端测试使用的 `testClient`(来自 `hono/testing`)
-- 前端调用使用的 `hc`(来自 `@hono/rpc`)
+- 前端 UI 包使用的 `rpcClient`(来自 `@d8d/shared-ui-components/utils/hc`)
 
 ### 核心映射规则
 
@@ -165,45 +166,60 @@ app.openapi(route, handler);
 const response = await client.admin['unified-advertisement-types'].$get();
 ```
 
-### 5. 前端 RPC Client (hc) 使用
+### 5. 前端 UI 包 RPC Client 使用
 
-**重要**: 前端使用 `hc` 创建的 RPC 客户端与 `testClient` 使用**完全相同的路径映射规则**。
+**重要**: 前端 UI 包使用 `rpcClient` 创建的 RPC 客户端与 `testClient` 使用**完全相同的路径映射规则**。
 
 ```typescript
-// 前端 API 客户端创建
-import { hc } from 'hono/client';
-import type { ApiRoutes } from '@d8d/server';
-
-export const apiClient = hc<ApiRoutes>('/api/v1');
-
-// 路由定义: path: '/' (在 server 包注册为 '/api/v1/admin/unified-advertisements')
-const response = await apiClient.admin['unified-advertisements'].$get({
+// 前端 API 客户端管理器(UI包标准模式)
+// src/api/<module>Client.ts
+import { <module>Routes } from '@d8d/<module-name>-module';
+import { rpcClient } from '@d8d/shared-ui-components/utils/hc'
+
+export class <Module>ClientManager {
+  private client: ReturnType<typeof rpcClient<typeof <module>Routes>> | null = null;
+
+  public init(baseUrl: string = '/'): ReturnType<typeof rpcClient<typeof <module>Routes>> {
+    return this.client = rpcClient<typeof <module>Routes>(baseUrl);
+  }
+
+  public get(): ReturnType<typeof rpcClient<typeof <module>Routes>> {
+    if (!this.client) {
+      return this.init();
+    }
+    return this.client;
+  }
+}
+
+// 使用示例
+const <module>ClientManager = <Module>ClientManager.getInstance();
+const client = <module>ClientManager.get();
+
+// 路由定义: path: '/' (在 server 包注册为 '/api/v1/admin/<module>s')
+const response = await client.index.$get({
   query: { page: 1, pageSize: 10 }
 });
 
 // 路由定义: path: '/:id'
-const response = await apiClient.admin['unified-advertisements'][':id'].$put({
+const response = await client[':id'].$put({
   param: { id: 123 },
   json: updateData
 });
 ```
 
 **关键点**:
-1. **hc 调用路径与 testClient 完全一致**: 如果测试用 `adminClient.$get()`,前端也用 `apiClient.admin.xxx.$get()`
-2. **不需要重复前缀**: hc 已经配置了 baseURL (`/api/v1`),调用时不需要再包含
+1. **rpcClient 调用路径与 testClient 完全一致**: 如果测试用 `adminClient.$get()`,前端也用 `client.index.$get()`
+2. **不需要重复前缀**: `rpcClient` 会配置 baseURL,调用时只需要使用路由的相对路径
 3. **类型安全**: TypeScript 会自动推断正确的路径和方法
 
-**错误示例**:
-```typescript
-// ❌ 错误: 重复包含 /api/v1 前缀
-const response = await apiClient['/api/v1/admin/unified-advertisements'].$get();
+**路由名称对应关系**:
+| 模块内路由定义 | Server注册 | rpcClient调用 |
+|--------------|-----------|--------------|
+| `path: '/'` | `.route('/api/v1/admin/<module>s', routes)` | `client.index.$get()` |
+| `path: '/:id'` | `.route('/api/v1/admin/<module>s', routes)` | `client[':id'].$get()` |
+| `path: '/search'` | 自定义路由 | `client.search.$get()` |
 
-// ❌ 错误: 中线路径用点号访问
-const response = await apiClient.admin.unified-advertisements.$get();
-
-// ✅ 正确: 使用方括号访问中线路径
-const response = await apiClient.admin['unified-advertisements'].$get();
-```
+**参考实现**: UI包开发规范 - RPC客户端实现规范
 
 ## 常见错误 ❌
 
@@ -413,13 +429,14 @@ await client.$get()  // path: '/'  →  .$get()
 
 - [后端模块包开发规范](./backend-module-package-standards.md) - 路由定义规范
 - [后端模块包测试规范](./backend-module-testing-standards.md) - 测试框架和集成测试
+- [UI包开发规范](./ui-package-standards.md) - RPC客户端实现规范
 - [编码标准](./coding-standards.md) - RPC API测试规范章节
 
 ---
 
 **文档状态**: 正式版
 **创建原因**: 故事010.003修复过程中发现缺乏testClient调用规范
-**适用范围**: 所有使用 Hono RPC 客户端的地方(testClient 和 hc)
+**适用范围**: 所有使用 Hono RPC 客户端的地方
 **覆盖范围**:
 - 后端集成测试 (`hono/testing` 的 `testClient`)
-- 前端 UI 包 RPC 调用 (`@hono/rpc` 的 `hc`)
+- 前端 UI 包 RPC 调用 (`@d8d/shared-ui-components/utils/hc` 的 `rpcClient`)