Переглянути джерело

📝 docs(prd): add RPC client architecture design and best practices

- add RPC client architecture design section, including singleton pattern implementation and key features
- add RPC client best practices covering client manager design, type-safe calls, and API invocation patterns
- provide TypeScript code examples for client manager, type inference, and API integration
- update last modified date to 2025-11-16
yourname 1 місяць тому
батько
коміт
fd997762b7
1 змінених файлів з 78 додано та 1 видалено
  1. 78 1
      docs/prd/epic-007-multi-tenant-package-replication.md

+ 78 - 1
docs/prd/epic-007-multi-tenant-package-replication.md

@@ -1019,6 +1019,83 @@ CREATE INDEX idx_goods_mt_tenant_id ON goods_mt(tenant_id);
 8. **UI组件测试**: 使用data-testid进行元素定位,比placeholder/role更准确稳定
 9. **FormField mock**: 正确处理render函数,确保子组件正确渲染
 
+10. **RPC客户端架构设计**
+   - **问题**: 独立包中需要统一的RPC客户端管理机制
+   - **解决方案**: 实现单例模式的RPC客户端管理器,支持延迟初始化和重置功能
+   - **关键设计**:
+     - 使用单例模式确保全局唯一的客户端实例
+     - 支持延迟初始化,避免循环依赖
+     - 提供reset方法用于测试和重新初始化
+     - 使用Hono的InferRequestType和InferResponseType进行类型安全
+   - **效果**: 提供稳定的RPC客户端架构,支持独立包和主应用的统一调用
+
+### RPC客户端最佳实践
+
+1. **客户端管理器设计**
+```typescript
+// 单例模式确保全局唯一实例
+class UserClientManager {
+  private static instance: UserClientManager;
+  private client: ReturnType<typeof rpcClient<typeof userRoutes>> | null = null;
+
+  // 初始化客户端
+  public init(baseUrl: string = '/'): ReturnType<typeof rpcClient<typeof userRoutes>> {
+    return this.client = rpcClient<typeof userRoutes>(baseUrl);
+  }
+
+  // 获取客户端实例(延迟初始化)
+  public get(): ReturnType<typeof rpcClient<typeof userRoutes>> {
+    if (!this.client) {
+      return this.init()
+    }
+    return this.client;
+  }
+
+  // 重置客户端(用于测试或重新初始化)
+  public reset(): void {
+    this.client = null;
+  }
+}
+```
+
+2. **类型安全调用**
+```typescript
+// 使用Hono类型推断确保类型安全
+type CreateUserRequest = InferRequestType<typeof userClient.index.$post>['json'];
+type UpdateUserRequest = InferRequestType<typeof userClient[':id']['$put']>['json'];
+type UserResponse = InferResponseType<typeof userClient.index.$get, 200>['data'][0];
+
+// 直接使用后端定义的schema
+const createUserFormSchema = CreateUserDto;
+const updateUserFormSchema = UpdateUserDto;
+```
+
+3. **API调用模式**
+```typescript
+// 使用客户端管理器进行API调用
+const res = await userClientManager.get().index.$get({
+  query: {
+    page: searchParams.page,
+    pageSize: searchParams.limit,
+    keyword: searchParams.keyword,
+    filters: Object.keys(filterParams).length > 0 ? JSON.stringify(filterParams) : undefined
+  }
+});
+
+// 创建用户
+const res = await userClientManager.get().index.$post({
+  json: data
+});
+```
+
+4. **主应用集成**
+```typescript
+// 在主应用中初始化客户端
+import { userClientManager } from '@d8d/user-management-ui/api';
+
+userClientManager.init('/api/v1/users');
+```
+
 ## 总结
 
 多租户复制包方案为用户提供了明确的实施路径:
@@ -1040,4 +1117,4 @@ via [Happy](https://happy.engineering)
 **Co-Authored-By: Claude <noreply@anthropic.com>**
 **Co-Authored-By: Happy <yesreply@happy.engineering>**
 
-**最后更新**: 2025-11-15 (添加管理界面独立包故事)
+**最后更新**: 2025-11-16 (添加RPC客户端架构设计和最佳实践)