• 简体中文
  • 接入 VextJS

    VextJS 是 commflow 的首个重点消费者,但 commflow core 保持框架无关。接入目标是把通信编排移到 commflow,同时保留 VextJS 的 request context、日志、hook 和 proxy 体验。

    当前发布版本: commflow@0.0.2 只提供 manifest API,没有 request runtime 或 VextJS adapter。VextJS 当前未公开 app.setFetch(),不能在插件中直接替换内置 app.fetch

    今天可用的 VextJS 方案: 使用 app.fetch.create() 创建专用子客户端,再用 app.extend() 挂载;它不替换 app.fetch,也不依赖尚未发布的 commflow runtime。

    今天先用 VextJS 的专用 client

    下面是 VextJS 已发布 API 的可运行形态,用于为某个下游服务创建独立 client:

    // src/plugins/service-clients.ts
    import { definePlugin } from 'vextjs';
    
    export default definePlugin({
      name: 'service-clients',
      setup(app) {
        app.extend('userClient', app.fetch.create({
          baseURL: process.env.USER_SERVICE_URL ?? 'http://user-service:3001',
          timeout: 5000,
          retry: 2
        }));
      }
    });

    这个子 client 是当前 VextJS app.fetch 的专用实例,不是 commflow client;它不会替换 app.fetch。如果你需要立即上线出站调用,请优先使用此方案或内置 app.fetch;若要核对当前 commflow 包,请看 当前版本快速开始

    接入前先核对现有能力

    VextJS 当前 app.fetch 已经承担以下职责。迁移不能只替换调用函数,还要逐项保留行为:

    app.fetch 能力commflow 承接位置兼容要求
    原生 fetch 与 GET/POST/PUT/PATCH/DELETErequest client继续返回原生 Response,不改变业务判断方式
    create({ baseURL, headers, timeout, retry })client / target 默认配置保留配置优先级和 header 合并规则
    timeoutrequest timeout用户 signal 与 timeout signal 都能中止请求
    幂等请求 retryretry policyGET/HEAD/OPTIONS/PUT/DELETE 可重试,POST/PATCH 默认不重试
    requestId 与自定义 header 透传VextJS contextProvider从当前 request context 读取,不要求业务代码手动传递
    出站生命周期 hook 与结构化日志hooks / adapter保留 method、URL、status、duration、requestId 与错误字段
    app.fetch.proxyVextJS adapter保留响应透传、header 白名单、Authorization 显式授权和客户端断开处理

    规划中的 commflow 接入路径(不是当前导入)

    阶段一:并行挂载

    commflow 发布 request runtime 后,可在 VextJS 插件中创建 request client,并通过 app.extend() 挂载独立入口。此阶段保留 app.fetch,先迁移一个低风险下游服务。

    import { createCommflowRequestClient } from 'commflow';
    import { definePlugin, requestContext } from 'vextjs';
    
    declare module 'vextjs' {
      interface VextConfig {
        services: {
          user: string;
        };
      }
    
      interface VextApp {
        commflow: ReturnType<typeof createCommflowRequestClient>;
      }
    }
    
    export default definePlugin({
      name: 'commflow',
      setup(app) {
        app.extend('commflow', createCommflowRequestClient({
          baseURL: app.config.services.user,
          timeout: 5000,
          retry: 1,
          contextProvider: () => ({
            requestId: requestContext.getStore()?.requestId
          })
        }));
      }
    });

    这是规划功能契约中的接入形态,不是 commflow@0.0.2 的可运行导入。并行挂载让你在不改变框架内置行为的前提下验证未来的 request core。

    配置文件需要给 services.user 明确来源:

    export default {
      services: {
        user: 'https://user-service.internal'
      }
    };

    app.extend() 只挂载出站 client 或辅助能力,不注册业务 route;需要入站 RPC/SSE/socket 路径时,由 src/routes/**defineRoutes() 挂载 handler。

    阶段二:按调用场景迁移

    按以下顺序迁移,避免同时改变所有失败语义:

    1. 无 proxy、无自定义 hook 的幂等 GET。
    2. 使用 create() 子客户端的服务间调用。
    3. 带 context/header 透传的调用。
    4. 非幂等写入和自定义 retry。
    5. proxy 与流式响应。

    每迁移一类,都要比较返回状态、异常类型、重试次数、日志字段和 requestId 传播。

    阶段三:替换框架内置路径

    只有当 VextJS 提供稳定注入点,且所有兼容检查通过后,才把 app.fetch 的底层实现切换到 commflow adapter。业务侧调用签名应保持稳定;框架专属的 request context、logger、hook 和 proxy bridge 留在 adapter,不能进入 framework-agnostic core。

    配置映射

    VextJS 配置commflow 配置迁移注意
    config.fetch.timeoutclient timeout单次调用覆盖优先
    config.fetch.retryclient retry数值表示额外尝试次数时要保持一致
    config.fetch.retryDelayretry delay / backoff保留函数形式的 attempt 语义
    config.fetch.propagateHeaderscontextProvider / adapter headers只从允许列表传播
    config.fetch.proxy[]adapter targetsproxy 的响应透传与普通 request 返回值不同

    兼容验收清单

    场景必须保持的结果
    2xx / 3xx / 4xx返回 Response,不把 4xx 自动改成 transport error
    最终 5xxretry 耗尽后仍返回最后一个 Response
    网络失败retry 耗尽后抛出 network error
    timeout中止请求并抛出 timeout error,不自动重试
    非幂等方法POST/PATCH 默认不自动重放
    requestId / trace header从当前 VextJS 上下文自动传给下游
    proxy原状态码与 body 透传;本地错误才映射为 VextJS 错误响应
    Authorization只有白名单和显式授权同时存在时才透传
    客户端断开取消正在进行的上游 proxy 请求并释放流

    其他通信方式

    request 接入稳定后,再按需要增加:

    • RPC:用 VextJS route 挂载 RPC handler,并把 typed client 挂到应用上下文。
    • SSE:复用 request context 和错误模型,单独管理订阅关闭与重连。
    • Socket:复用 metadata 与错误归一,保留独立的连接、心跳和重连生命周期。

    当前版本怎么使用

    如果你正在使用 commflow@0.0.2,不要导入本页规划部分的 request client。先运行 当前版本快速开始 验证 manifest;今天需要 VextJS 出站 client 时,使用上文的 app.fetch.create() + app.extend() 方案。