You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

生成支持多内容类型、自定义序列化与鉴别器的OpenAPI TS客户端

解决方案:用OpenAPI Generator定制TypeScript客户端支持BCS与鉴别器

核心思路

选OpenAPI Generator的typescript-fetch生成器,它支持自定义模板和扩展点,能覆盖多Content-Type、鉴别器解析、BCS序列化注入的全部需求。

步骤1:基础客户端生成

先生成带鉴别器支持的基础TS客户端,执行以下命令:

openapi-generator generate \
  -i your-api-spec.yaml \
  -g typescript-fetch \
  -o ./generated-client \
  --additional-properties=discriminatorUsePolymorphism=true,typescriptThreePlus=true
  • discriminatorUsePolymorphism=true:启用多态类型生成,自动处理oneOf/allOf结构的鉴别器逻辑
  • typescriptThreePlus=true:生成符合TS3+语法的代码

步骤2:扩展BCS序列化/反序列化能力

1. 编写BCS工具类

在生成的客户端目录下创建bcs-utils.ts,封装BCS处理逻辑:

// 替换为你实际使用的BCS库
import { BCS } from '@mysten/bcs';

export const bcs = new BCS({ encoding: 'base64' });

// 注册OpenAPI中定义的所有Schema类型
bcs.registerStructType('GenesisTransaction', { /* 匹配你的类型结构 */ });
bcs.registerStructType('UserTransaction', { /* 匹配你的类型结构 */ });
bcs.registerStructType('SubmitTransactionRequest', { /* 匹配你的类型结构 */ });
// ... 其他需要处理的类型

export function serializeToBCS<T>(data: T, typeName: string): Uint8Array {
  return bcs.serialize(typeName, data);
}

export function deserializeFromBCS<T>(bytes: Uint8Array, typeName: string): T {
  return bcs.deserialize(typeName, bytes);
}

2. 修改核心请求类,注入格式自动切换逻辑

找到生成的ApiClient.ts(或类似核心请求文件),修改request方法,根据请求头自动处理序列化/反序列化:

async request<T>(context: RequestContext): Promise<T> {
  let body: any = context.body;
  // 处理请求序列化:根据Content-Type选择格式
  if (context.headers['Content-Type'] === 'application/x-bcs') {
    // 根据API路径、方法映射对应的Schema类型名,可手动维护或通过模板自动生成
    const typeName = getRequestTypeName(context.path, context.method);
    body = serializeToBCS(body, typeName);
  } else {
    body = JSON.stringify(body);
  }

  const response = await fetch(context.url, {
    method: context.method,
    headers: context.headers,
    body,
  });

  // 处理响应反序列化:根据Accept头选择格式
  const acceptHeader = context.headers['Accept'] || 'application/json';
  let responseData: any;
  if (acceptHeader === 'application/x-bcs') {
    const bytes = await response.arrayBuffer();
    const typeName = getResponseTypeName(context.path, context.method, response.status);
    responseData = deserializeFromBCS(new Uint8Array(bytes), typeName);
  } else {
    responseData = await response.json();
  }

  // 生成的代码已包含鉴别器类型转换逻辑,直接返回即可
  return responseData as T;
}

注:getRequestTypeName和getResponseTypeName需根据API路径、方法、状态码映射到对应的Schema名称,可手动维护映射表,或通过自定义模板自动化生成。

3. 自定义模板(可选,自动化类型映射)

若要避免手动维护类型映射,可自定义OpenAPI Generator模板:

  • 复制typescript-fetch官方模板中的api.mustache文件到本地
  • 修改模板,在生成API方法时自动注入对应的Schema类型名,生成映射表
  • 重新生成时添加--template-dir=./your-custom-templates参数指定模板目录

步骤3:使用生成的客户端

调用API时只需指定请求头,即可自动切换JSON/BCS格式:

import { TransactionApi, SubmitTransactionRequest } from './generated-client';

const api = new TransactionApi({ basePath: 'https://your-api-server.com' });

// 发送BCS请求,接收BCS响应
const bcsRequest: SubmitTransactionRequest = { /* 请求数据 */ };
const bcsResponse = await api.createTransaction(bcsRequest, {
  headers: {
    'Content-Type': 'application/x-bcs',
    'Accept': 'application/x-bcs',
  },
});

// 发送JSON请求,接收JSON响应
const jsonResponse = await api.createTransaction(bcsRequest, {
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
  },
});

关键特性验证

  • 多格式支持:通过Content-Type和Accept头自动切换序列化/反序列化逻辑
  • 鉴别器处理:生成的代码会自动识别type鉴别字段,完成oneOf/allOf类型的转换
  • BCS封装:序列化逻辑完全封装在客户端内部,业务代码无需关心底层实现

内容的提问来源于stack exchange,提问作者Daniel Porteous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 20:27:18