OpenAPI(Alpha 阶段)
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
此包处于 Alpha 阶段,API 可能随时变更且不另行通知。
@trpc/openapi 包可根据您的 tRPC 路由生成 OpenAPI 3.1 规范。生成的规范可用于:
-
生成任意语言的类型化 API 客户端
-
通过 Postman 或 Insomnia 等 HTTP 工具调用 tRPC 端点
-
实现 AI 代理集成(如 MCP 服务器)
安装
bashpnpm add @trpc/openapi
bashpnpm add @trpc/openapi
若您使用 AI 编程代理,请安装 tRPC 技能以优化代码生成效果:
bashnpx @tanstack/intent@latest install
bashnpx @tanstack/intent@latest install
@trpc/openapi 当前版本号为 11.x.x-alpha,兼容所有新版 tRPC v11,但建议保持版本号一致
调整 tRPC 配置
生成器可直接处理现有路由,无需额外注解或装饰器。需注意以下事项:
-
无需声明输出类型 — 与其他 OpenAPI 工具不同,
.output()模式是可选的,生成器会自动从实现中推断返回类型 -
订阅功能 — 当前不包含在规范中,SSE 支持已在规划中
-
描述信息 — Zod 的
.describe()调用及 JSDoc 注释(类型/路由/过程)将自动转为规范中的description字段
生成规范
CLI 方式
bashpnpm exec trpc-openapi ./src/server/router.ts
bashpnpm exec trpc-openapi ./src/server/router.ts
| Option | Default | Description |
|---|---|---|
-e, --export <name> | AppRouter | Name of the exported router type |
-o, --output <file> | openapi.json | Output file path |
--title <text> | tRPC API | OpenAPI info.title |
--version <ver> | 0.0.0 | OpenAPI info.version |
bashpnpm exec trpc-openapi ./src/server/router.ts -o api.json --title "My API" --version 1.0.0
bashpnpm exec trpc-openapi ./src/server/router.ts -o api.json --title "My API" --version 1.0.0
编程式调用
scripts/generate-openapi.tstsimport { generateOpenAPIDocument } from '@trpc/openapi';const doc = generateOpenAPIDocument('./src/server/router.ts', {exportName: 'AppRouter',title: 'My API',version: '1.0.0',});
scripts/generate-openapi.tstsimport { generateOpenAPIDocument } from '@trpc/openapi';const doc = generateOpenAPIDocument('./src/server/router.ts', {exportName: 'AppRouter',title: 'My API',version: '1.0.0',});
生成器通过静态分析路由的 TypeScript 类型工作,不会执行实际代码
根据规范生成客户端
任意 OpenAPI 客户端生成器均可使用,但最成熟的集成方案是 Hey API
生成的客户端将提供与 tRPC 过程匹配的类型化 SDK 函数:
-
查询操作 →
GET /procedure.path -
变更操作 →
POST /procedure.path -
订阅操作 暂不支持(SSE 即将推出)
Hey API(TypeScript)
bashpnpm add @trpc/openapi @hey-api/openapi-ts
bashpnpm add @trpc/openapi @hey-api/openapi-ts
默认情况下,OpenAPI 生成的客户端无法识别转换器配置和查询参数编码方式。@trpc/openapi/heyapi 包提供的 configureTRPCHeyApiClient 工具可解决此问题 — 它配置了请求序列化、响应解析和错误反序列化逻辑,确保 SDK 与 tRPC 端点正确协作
无转换器场景
此时可通过 Hey API 的 CLI 或编程接口生成客户端
bashpnpm exec openapi-ts -i openapi.json -o ./generated
bashpnpm exec openapi-ts -i openapi.json -o ./generated
运行时需进行简单配置:
src/usage.tstsimport { configureTRPCHeyApiClient } from '@trpc/openapi/heyapi';import { client } from './generated/client.gen';import { Sdk } from './generated/sdk.gen';configureTRPCHeyApiClient(client, {baseUrl: 'http://localhost:3000',});const sdk = new Sdk({ client });const result = await sdk.greeting({ query: { input: { name: 'World' } } });const user = await sdk.user.create({ body: { name: 'Bob', age: 30 } });
src/usage.tstsimport { configureTRPCHeyApiClient } from '@trpc/openapi/heyapi';import { client } from './generated/client.gen';import { Sdk } from './generated/sdk.gen';configureTRPCHeyApiClient(client, {baseUrl: 'http://localhost:3000',});const sdk = new Sdk({ client });const result = await sdk.greeting({ query: { input: { name: 'World' } } });const user = await sdk.user.create({ body: { name: 'Bob', age: 30 } });
使用转换器(superjson/devalue 等)
若后端使用了 数据转换器(如 superjson),必须将其传入客户端配置。否则日期、Map/Set 等非 JSON 类型可能产生静默错误
首先通过 Hey API 编程接口生成客户端代码,使用 createTRPCHeyApiTypeResolvers 确保类型正确性:
src/client.tstsimport { createClient } from '@hey-api/openapi-ts';import { createTRPCHeyApiTypeResolvers } from '@trpc/openapi/heyapi';const openApiJson = './path/to/openapi.json'const outputDir = './generated'await createClient({input: openApiJson,output: outputDir,plugins: [{name: '@hey-api/typescript',// Important: this ensures that your emitted types like Dates are correct'~resolvers': createTRPCHeyApiTypeResolvers(),},{name: '@hey-api/sdk',operations: { strategy: 'single' },},],});
src/client.tstsimport { createClient } from '@hey-api/openapi-ts';import { createTRPCHeyApiTypeResolvers } from '@trpc/openapi/heyapi';const openApiJson = './path/to/openapi.json'const outputDir = './generated'await createClient({input: openApiJson,output: outputDir,plugins: [{name: '@hey-api/typescript',// Important: this ensures that your emitted types like Dates are correct'~resolvers': createTRPCHeyApiTypeResolvers(),},{name: '@hey-api/sdk',operations: { strategy: 'single' },},],});
运行时配置转换器后,即可直接传入原生类型并获取反序列化结果:
src/usage.tstsimport { configureTRPCHeyApiClient } from '@trpc/openapi/heyapi';import superjson from 'superjson';import { client } from './generated/client.gen';configureTRPCHeyApiClient(client, {baseUrl: 'http://localhost:3000',// Important, this transformer must match your tRPC API's transformer:transformer: superjson,});const sdk = new Sdk({ client });const event = await sdk.getEvent({query: { input: { id: 'evt_1', at: new Date('2025-06-15T10:00:00Z') } },});// event.data.result.data.at is a Date object ✅const created = await sdk.createEvent({body: { name: 'Conference', at: new Date('2025-09-01T09:00:00Z') },});
src/usage.tstsimport { configureTRPCHeyApiClient } from '@trpc/openapi/heyapi';import superjson from 'superjson';import { client } from './generated/client.gen';configureTRPCHeyApiClient(client, {baseUrl: 'http://localhost:3000',// Important, this transformer must match your tRPC API's transformer:transformer: superjson,});const sdk = new Sdk({ client });const event = await sdk.getEvent({query: { input: { id: 'evt_1', at: new Date('2025-06-15T10:00:00Z') } },});// event.data.result.data.at is a Date object ✅const created = await sdk.createEvent({body: { name: 'Conference', at: new Date('2025-09-01T09:00:00Z') },});
使用其他生成器或语言
生成的 OpenAPI 规范适用于任何兼容 OpenAPI 的客户端生成器,需要满足以下条件:
-
能为 Date 等类生成精确的类型定义
-
支持自定义查询参数和请求/响应体的序列化方式
为确保与 tRPC 协议正确集成,生成的客户端需实现以下两点:
-
数据转换器 — 如果 tRPC API 使用了数据转换器,客户端必须采用相同格式序列化输入并反序列化输出
-
查询输入 — GET 请求需将输入编码为
?input=<JSON>形式,而非拆分为独立查询参数
完整参考实现请见 Hey API 配置源码。
数据转换器
tRPC 数据转换器支持在传输中处理 Date、Map、Set 和 BigInt 等丰富类型。使用 OpenAPI 客户端时,服务端和客户端必须配置相同的转换器,以确保输入正确序列化且输出正确反序列化。
任何实现 tRPC DataTransformer 接口(提供 serialize/deserialize 方法)的转换器都能与 configureTRPCHeyApiClient 协同工作。以下是经过验证的选项:
SuperJSON
TypeScript 项目最流行的转换器,支持处理 Date、Map、Set、BigInt、RegExp 等类型。
bashpnpm add superjson
bashpnpm add superjson
src/server.tstsimport { initTRPC } from '@trpc/server';import superjson from 'superjson';const t = initTRPC.create({ transformer: superjson });
src/server.tstsimport { initTRPC } from '@trpc/server';import superjson from 'superjson';const t = initTRPC.create({ transformer: superjson });
src/client.tstsimport { configureTRPCHeyApiClient } from '@trpc/openapi/heyapi';import superjson from 'superjson';import { client } from './generated/client.gen';configureTRPCHeyApiClient(client, {baseUrl: 'http://localhost:3000',transformer: superjson,});
src/client.tstsimport { configureTRPCHeyApiClient } from '@trpc/openapi/heyapi';import superjson from 'superjson';import { client } from './generated/client.gen';configureTRPCHeyApiClient(client, {baseUrl: 'http://localhost:3000',transformer: superjson,});
完整端到端示例请参考 superjson 测试。
MongoDB 扩展 JSON v2
EJSON 是实现跨语言支持的理想选择。通过 bson npm 包的 EJSON.serialize/EJSON.deserialize 可直接实现 tRPC DataTransformer 接口。
支持语言:C, C#, C++, Go, Java, Node.js, Perl, PHP, Python, Ruby, Scala
bashpnpm add bson
bashpnpm add bson
src/transformer.tstsimport { EJSON } from 'bson';import type { TRPCDataTransformer } from '@trpc/server';export const ejsonTransformer: TRPCDataTransformer = {serialize: (value) => EJSON.serialize(value),deserialize: (value) => EJSON.deserialize(value as Document),};
src/transformer.tstsimport { EJSON } from 'bson';import type { TRPCDataTransformer } from '@trpc/server';export const ejsonTransformer: TRPCDataTransformer = {serialize: (value) => EJSON.serialize(value),deserialize: (value) => EJSON.deserialize(value as Document),};
src/client.tstsimport { configureTRPCHeyApiClient } from '@trpc/openapi/heyapi';import { client } from './generated/client.gen';import { ejsonTransformer } from './transformer';configureTRPCHeyApiClient(client, {baseUrl: 'http://localhost:3000',transformer: ejsonTransformer,});
src/client.tstsimport { configureTRPCHeyApiClient } from '@trpc/openapi/heyapi';import { client } from './generated/client.gen';import { ejsonTransformer } from './transformer';configureTRPCHeyApiClient(client, {baseUrl: 'http://localhost:3000',transformer: ejsonTransformer,});
完整端到端示例请参考 MongoDB EJSON 测试。
Amazon Ion
Amazon Ion 是具有丰富类型的数据格式且支持广泛语言。虽然不直接兼容 TRPCDataTransformer 接口,在 JS/TS 中需编写胶水代码,但在特定系统中有其优势。
支持语言:C, C#, D, Go, Java, JavaScript, PHP, Python, Rust
bashpnpm add ion-js
bashpnpm add ion-js
转换器实现和完整端到端示例请参考 Amazon Ion 测试。
编写自定义转换器
任何包含 serialize 和 deserialize 方法的对象均可作为转换器:
tsimport type { TRPCDataTransformer } from '@trpc/server';const myTransformer: TRPCDataTransformer = {serialize: (value) => {/* encode rich types */},deserialize: (value) => {/* decode them back */},};
tsimport type { TRPCDataTransformer } from '@trpc/server';const myTransformer: TRPCDataTransformer = {serialize: (value) => {/* encode rich types */},deserialize: (value) => {/* decode them back */},};
在服务端通过 initTRPC.create({ transformer }) 配置,在客户端通过 configureTRPCHeyApiClient(client, { transformer }) 配置。详见数据转换器文档。
完整示例
可运行的完整项目请参考 openapi-codegen 示例。