核心是通过 Proxy 的 get 和 apply 实现路径累积与延迟执行,使 api.user.profile.get() 等调用链动态可追踪;每次属性访问返回带 path 的新 Proxy 并缓存复用,get 拦截 then 防止误判 Promise,apply 阶段拼接路径、序列化参数并发起请求,支持按需增强、取消、超时重试及 TypeScript 类型推导。

核心在于用 Proxy 的 get 和 apply 配合路径累积与延迟执行,把“调用链”变成可追踪、可拦截、可扩展的动态结构,而不是静态绑定接口。
路径式代理:让 api.user.profile.get() 真正走通
RPC 方法名往往嵌套多层(如 api.order.payment.confirm),不能只代理顶层对象。每次访问属性(user、profile)都必须返回一个新 Proxy,并携带当前完整路径。关键点:
-
路径不存于原始对象,而是通过私有字段(如
{ path: ["api", "user"] })在每个代理实例中隐式传递 - 避免重复创建:用 Map 缓存已生成的路径代理,相同路径复用同一 Proxy 实例
-
拦截 Promise 检测:在
get中对"then"返回undefined,防止被await误判为 Promise 而提前触发
调用即请求:所有逻辑收口到 apply 阶段
真正发起网络请求不能发生在 get,而必须等到函数被调用——也就是 apply 触发时。此时你已拥有完整路径和全部参数:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
-
路径拼接:将
target.path(如["user", "list"])转为字符串"user.list",作为 API 路由后缀 -
参数序列化:把
args直接 JSON 序列化为请求体,无需手动拆解或映射 -
统一响应处理:fetch 后统一
.json()解析,错误可在此集中 throw 或包装
按需增强:在调用前注入元能力
“按需”不只是懒加载代码,更是按首次调用动态加载行为。比如可在 apply 中检查是否首次执行某方法,然后:
- 自动拉取该方法的 schema,做参数校验
- 预热 HTTP 连接池或建立长连接
- 读取服务端权限配置,插入 auth token
- 记录方法级埋点,用于后续性能分析
兼容性与健壮性设计
真实 RPC 客户端要应对各种边界情况:
-
非函数属性访问:若用户写
rpc.version,get应返回undefined或抛出明确提示,而非静默返回 Proxy -
取消请求支持:在
apply中接入AbortController,允许上层传入 signal - 超时与重试封装:不在 fetch 外层硬写,而是作为可插拔中间件注入到调用链中
- 类型提示友好:配合 TypeScript,用泛型 + 路径字符串字面量推导返回类型,提升开发体验

















