跳至主内容
版本:11.x

OpenAPI(Alpha 阶段)

非官方测试版翻译

本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →

注意

此包处于 Alpha 阶段,API 可能随时变更且不另行通知。

@trpc/openapi 包可根据您的 tRPC 路由生成 OpenAPI 3.1 规范。生成的规范可用于:

  • 生成任意语言的类型化 API 客户端

  • 通过 Postman 或 Insomnia 等 HTTP 工具调用 tRPC 端点

  • 实现 AI 代理集成(如 MCP 服务器)

安装

bash
pnpm add @trpc/openapi
bash
pnpm add @trpc/openapi
AI 代理

若您使用 AI 编程代理,请安装 tRPC 技能以优化代码生成效果:

bash
npx @tanstack/intent@latest install
bash
npx @tanstack/intent@latest install
备注

@trpc/openapi 当前版本号为 11.x.x-alpha,兼容所有新版 tRPC v11,但建议保持版本号一致

调整 tRPC 配置

生成器可直接处理现有路由,无需额外注解或装饰器。需注意以下事项:

  • 无需声明输出类型 — 与其他 OpenAPI 工具不同,.output() 模式是可选的,生成器会自动从实现中推断返回类型

  • 数据转换器 — 若服务端使用了数据转换器,客户端必须使用相同配置。详见转换器的跨语言实现方案

  • 订阅功能 — 当前不包含在规范中,SSE 支持已在规划中

  • 描述信息 — Zod 的 .describe() 调用及 JSDoc 注释(类型/路由/过程)将自动转为规范中的 description 字段

生成规范

CLI 方式

bash
pnpm exec trpc-openapi ./src/server/router.ts
bash
pnpm exec trpc-openapi ./src/server/router.ts
OptionDefaultDescription
-e, --export <name>AppRouterName of the exported router type
-o, --output <file>openapi.jsonOutput file path
--title <text>tRPC APIOpenAPI info.title
--version <ver>0.0.0OpenAPI info.version
bash
pnpm exec trpc-openapi ./src/server/router.ts -o api.json --title "My API" --version 1.0.0
bash
pnpm exec trpc-openapi ./src/server/router.ts -o api.json --title "My API" --version 1.0.0

编程式调用

scripts/generate-openapi.ts
ts
import { generateOpenAPIDocument } from '@trpc/openapi';
const doc = generateOpenAPIDocument('./src/server/router.ts', {
exportName: 'AppRouter',
title: 'My API',
version: '1.0.0',
});
scripts/generate-openapi.ts
ts
import { 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)

Hey API 文档

bash
pnpm add @trpc/openapi @hey-api/openapi-ts
bash
pnpm add @trpc/openapi @hey-api/openapi-ts

默认情况下,OpenAPI 生成的客户端无法识别转换器配置和查询参数编码方式。@trpc/openapi/heyapi 包提供的 configureTRPCHeyApiClient 工具可解决此问题 — 它配置了请求序列化、响应解析和错误反序列化逻辑,确保 SDK 与 tRPC 端点正确协作

无转换器场景

此时可通过 Hey API 的 CLI 或编程接口生成客户端

bash
pnpm exec openapi-ts -i openapi.json -o ./generated
bash
pnpm exec openapi-ts -i openapi.json -o ./generated

运行时需进行简单配置:

src/usage.ts
ts
import { 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.ts
ts
import { 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.ts
ts
import { 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.ts
ts
import { 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.ts
ts
import { 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.ts
ts
import { 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 数据转换器支持在传输中处理 DateMapSetBigInt 等丰富类型。使用 OpenAPI 客户端时,服务端和客户端必须配置相同的转换器,以确保输入正确序列化且输出正确反序列化。

任何实现 tRPC DataTransformer 接口(提供 serialize/deserialize 方法)的转换器都能与 configureTRPCHeyApiClient 协同工作。以下是经过验证的选项:

SuperJSON

TypeScript 项目最流行的转换器,支持处理 DateMapSetBigIntRegExp 等类型。

bash
pnpm add superjson
bash
pnpm add superjson
src/server.ts
ts
import { initTRPC } from '@trpc/server';
import superjson from 'superjson';
const t = initTRPC.create({ transformer: superjson });
src/server.ts
ts
import { initTRPC } from '@trpc/server';
import superjson from 'superjson';
const t = initTRPC.create({ transformer: superjson });
src/client.ts
ts
import { 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.ts
ts
import { 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

bash
pnpm add bson
bash
pnpm add bson
src/transformer.ts
ts
import { 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.ts
ts
import { 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.ts
ts
import { 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.ts
ts
import { 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

bash
pnpm add ion-js
bash
pnpm add ion-js

转换器实现和完整端到端示例请参考 Amazon Ion 测试

编写自定义转换器

任何包含 serializedeserialize 方法的对象均可作为转换器:

ts
import type { TRPCDataTransformer } from '@trpc/server';
const myTransformer: TRPCDataTransformer = {
serialize: (value) => {
/* encode rich types */
},
deserialize: (value) => {
/* decode them back */
},
};
ts
import 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 示例