# 演进契约并兼容旧客户端

提供带版本的服务、转换旧契约并验证输入与输出。

本页介绍 WU Framework `4.0.0`。升级现有项目之前，请阅读 [Framework 4.0 与 CLI 1.2 迁移指南](/zh-cn/docs/guides/releases/)。

`wu-framework/services` 通过 schema 定义契约、验证调用并生成客户端。`provideService` 返回 `{ dispose }`，`consumeService` 返回异步方法。在应用内使用 `context.wu`，并为服务通道授予 `rpc.provide` 或 `rpc.call`。此示例使用宿主运行时来展示版本转换。

```js
import { wu } from 'wu-framework';
import { schema, defineService, provideService, consumeService,
  checkServiceCompatibility } from 'wu-framework/services';

const v1 = defineService({ name: 'price', version: '1.0.0', methods: {
  quote: { input: schema.number(), output: schema.number() },
} });
const v2 = defineService({ name: 'price', version: '2.0.0', methods: {
  quote: { input: schema.object({ quantity: schema.number() }),
    output: schema.object({ total: schema.number() }) },
} });
const translators = [{ definition: v1, methods: {
  quote: { input: quantity => ({ quantity }), output: result => result.total },
} }];
const provider = provideService(wu, v2, {
  quote: ({ quantity }) => ({ total: quantity * 12 }),
}, { translators });
try {
  const oldClient = consumeService(wu, v1);
  const newClient = consumeService(wu, v2);
  console.log(await oldClient.quote(2)); // 24
  console.log(await newClient.quote({ quantity: 2 })); // { total: 24 }
  console.log(checkServiceCompatibility(v1, v2, { translators }));
} finally {
  provider.dispose();
}
```

<span id="qué-se-valida"></span>

<span class="section-anchor" id="section-1"></span>

## 验证内容

每个转换器声明 `definition` 以及逐方法适配：`input`、`output`，或用 `implement` 完整处理已删除方法。不变的方法无需转换。WU 在注册时检查覆盖范围，并根据对应版本的 schema 验证每次输入输出。不完整覆盖会产生 `WU_SERVICE_TRANSLATOR`；结构检查并不证明转换函数保持了业务语义。

`checkServiceCompatibility(previous, next, { translators })` 返回 `compatible`、`changes` 与 `translated`。`generateServiceTypes` 生成客户端声明，`sampleValue(schema)` 创建确定性测试数据。在 CI 和开发中复用契约，请参阅 [CLI 契约](/zh-cn/docs/cli/contracts/) 与 [测试和 mock](/zh-cn/docs/cli/testing-mocks/)。

<span id="rpc-y-objetos-versionados"></span>

<span class="section-anchor" id="section-2"></span>

## 带版本的 RPC 与对象

`wu.handle(channel, handler, { version, translators })` 也支持直接转换。`translators` 的每个键表示可服务的版本，包含 `request` 与 `response`。上下文提供 `version`、`servedVersion` 和 `translated`；`WU_RPC_TRANSLATION_FAILED` 标明失败阶段。共享服务中，`wu.provide` 接受用于构建旧对象视图的转换器，`wu.consume` 通过 `__wuVersion` 暴露所服务的版本。