# @dokploy/trpc-openapi 中文文档

规范地址：https://npmcn.com/package/%40dokploy/trpc-openapi/

版本：0\.0\.19
npm 元数据更新时间：2026-04-11T20:48:51.341Z
中文译文更新时间：2026-11-12T15:12:07.720Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40dokploy/trpc-openapi
原文对照：https://npmcn.com/package/%40dokploy/trpc-openapi/?lang=original
项目主页：https://github.com/dokploy/trpc-openapi
源码仓库：https://github.com/dokploy/trpc-openapi

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：303 kB，187 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：3 个
- peer 依赖：@trpc/server ^11\.1\.0，zod ^4\.3\.6，zod-openapi ^5\.0\.1
- 首次发布：2024-06-23T16:39:18.607Z
- 最新版本发布：2026-04-11T20:48:51.197Z
- 近 30 天下载量：15273（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：20（近 12 个月 16 个）

## 中文简介

tRPC 打开API

## 安装

```sh
npm install @dokploy/trpc-openapi
```

也可以使用：`pnpm add @dokploy/trpc-openapi`、`yarn add @dokploy/trpc-openapi`、`bun add @dokploy/trpc-openapi`

## README

![](https://npmcn.com/package/%40dokploy/trpc-openapi/assets/trpc-openapi.svg)

# trpc- to- openapi 读取

[![](https://img.shields.io/npm/v/trpc-to-openapi.svg?style=flat&color=brightgreen)](https://www.npmjs.com/package/trpc-to-openapi) [![](https://img.shields.io/badge/license-MIT-black)](https://npmcn.com/package/%40dokploy/trpc-openapi/LICENSE)  

* * *

## **[打开API](https://swagger.io/specification/) 支持 [tRPC 主题](https://trpc.io/)** 🧩

-   对tRPC ^11.1.0的支持
-   您的 tRPC 程序的简单 REST 端点 .
-   适合逐步收养.
-   支持所有 OpenAPI 版本.

说明: 这个项目是分叉一分叉,完全归功于原作者. 看来原作者放弃了这个项目,所以我计划在不久的将来增加新的功能.

### 自定义( Dokploy- style)

此分叉增加了以下行为( 灵感来自 [多克宝利](https://github.com/Dokploy/dokploy):

1.  **默认需要可选输入和输出参数** – 在生成的OpenAPI文档中,可选输入/输出参数按需要处理.
2.  **`.meta` 对所有程序都是可选的** - 无程序 `.meta({ openapi: ... })` 仍然以默认的 OpenAPI 元数据(从程序类型、从程序路径、, `enabled: true`, (中文(简体) ), `protect: true`) (中文(简体) ).
3.  **两面旗 `meta.openapi`**数字 :
    -   **`override`** - 当 `true`,只提供 `openapi` 对象被使用(没有合并默认值).
    -   **`additional`** - 当 `true`,默认值先应用,然后应用 `openapi` 数值在上方合并.

## 使用量

**1\. 安装 `trpc-to-openapi`。 。 。 .**

```bash
# pnpm
pnpm add trpc-to-openapi
# npm
npm install trpc-to-openapi
# yarn
yarn add trpc-to-openapi
```

**2\. 添加 `OpenApiMeta` 给你的TRPC实例.**

```typescript
import { initTRPC } from '@trpc/server';
import { OpenApiMeta } from 'trpc-to-openapi';

const t = initTRPC.meta<OpenApiMeta>().create(); /* 👈 */
```

**3\. 启用 `openapi` 支持一个程序.**

```typescript
export const appRouter = t.router({
  sayHello: t.procedure
    .meta({ /* 👉 */ openapi: { method: 'GET', path: '/say-hello' } })
    .input(z.object({ name: z.string() }))
    .output(z.object({ greeting: z.string() }))
    .query(({ input }) => {
      return { greeting: `Hello ${input.name}!` };
    }),

  getStatus: t.procedure
    .meta({ /* 👉 */ openapi: { method: 'GET', path: '/status' } })
    .output(z.object({ status: z.string() }))
    .query(() => {
      return { status: 'healthy' };
    });
});
```

**4\. 生成 OpenAPI 文档.**

```typescript
import { generateOpenApiDocument } from 'trpc-to-openapi';

import { appRouter } from '../appRouter';
import { UserSchema, ProductSchema } from '../schemas';

/* 👇 */
export const openApiDocument = generateOpenApiDocument(appRouter, {
  title: 'tRPC OpenAPI',
  version: '1.0.0',
  baseUrl: 'http://localhost:3000',
  defs: {
    UserSchema,
    ProductSchema,
  },
});
```

**5\. 增加一个 `trpc-to-openapi` 操作员到你的应用程序.**

我们目前支持适配器 [`Express`](http://expressjs.com/), (中文(简体) ), [`Next.js`](https://nextjs.org/), (中文(简体) ), [`Fastify`](https://www.fastify.io/), (中文(简体) ), [`Nuxt`](https://nuxtjs.org/) 打开 [`Node:HTTP`](https://nodejs.org/api/http.html)。 。 。 .

[`Fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API), (中文(简体) ), [`Cloudflare Workers`](https://workers.cloudflare.com/) 更快的TM,PR受到欢迎.

没有支持 AWS lambdas

```typescript
import http from 'http';
import { createOpenApiHttpHandler } from 'trpc-to-openapi';

import { appRouter } from '../appRouter';

const server = http.createServer(createOpenApiHttpHandler({ router: appRouter })); /* 👈 */

server.listen(3000);
```

**6\. 利润**

```typescript
// client.ts
const res = await fetch('http://localhost:3000/say-hello?name=OpenAPI', { method: 'GET' });
const body = await res.json(); /* { greeting: 'Hello OpenAPI!' } */

const statusRes = await fetch('http://localhost:3000/status', { method: 'GET' });
const statusBody = await statusRes.json(); /* { status: 'healthy' } */
```

## 所需资源

同伴依赖性 :

-   [`tRPC`](https://github.com/trpc/trpc) 服务器 v11 (`@trpc/server`)必须安装.
-   [`Zod`](https://github.com/colinhacks/zod) v4 (中文(简体) )`zod@^4.0.0`)必须安装.

支持 OpenAPI 的程序如下: _必须_ 事实 :

-   一个 `output` 解析器已存在并使用 `Zod` 审定.
-   如果一个 `input` 解析器存在, 它必须使用 `Zod` 审定.
-   查询 `input` 解析器( 当当前) 延伸 `Object<{ [string]: String | Number | BigInt | Date }>` 或者说 `Void`。 。 。 .
-   变异 `input` 解析器( 当当前) 延伸 `Object<{ [string]: AnyType }>` 或者说 `Void`。 。 。 .
-   `meta.openapi.method` 实值 `GET`, (中文(简体) ), `POST`, (中文(简体) ), `PATCH`, (中文(简体) ), `PUT` 或者说 `DELETE`。 。 。 .
-   `meta.openapi.path` 是一个字符串,从 `/`。 。 。 .
-   `meta.openapi.path` 参数(当存在时)存在于 `input` 解析为 `String | Number | BigInt | Date`

请注意:

-   数据 [`transformers`](https://trpc.io/docs/data-transformers) (例如: `superjson`)被忽略.
-   被轻视了.
-   修行是无相相相.

## HTTP 请求

程序a `GET`编号 :`DELETE` 方法将通过 URL 接受输入 `query parameters`A. 程序与 `POST`编号 :`PATCH`编号 :`PUT` 方法将通过 `request body` 带有 `application/json` 内容类型.

### 路径参数

一个程序可以通过URL路径参数接受一组输入. 您可以在 OpenAPI 程序中使用输入名称周围的圆括号作为路径段添加路径参数 `meta.openapi.path` 字段.

### 查询参数

查询路径参数输入总是被接受为 `string`。该图书馆将试图 [胁迫](https://github.com/colinhacks/zod#coercion-for-primitives) 框中以下原始类型的输入值: `number`, (中文(简体) ), `boolean`, (中文(简体) ), `bigint` 财务报告和审定财务报表 `date`。如果您希望支持诸如 `object`, (中文(简体) ), `array` 请使用 [`z.preprocess()`](https://github.com/colinhacks/zod#preprocess)。 。 。 .

```typescript
// Router
export const appRouter = t.router({
  sayHello: t.procedure
    .meta({ openapi: { method: 'GET', path: '/say-hello/{name}' /* 👈 */ } })
    .input(z.object({ name: z.string() /* 👈 */, greeting: z.string() }))
    .output(z.object({ greeting: z.string() }))
    .query(({ input }) => {
      return { greeting: `${input.greeting} ${input.name}!` };
    });
});

// Client
const res = await fetch('http://localhost:3000/say-hello/Lily?greeting=Hello' /* 👈 */, {
  method: 'GET',
});
const body = await res.json(); /* { greeting: 'Hello Lily!' } */
```

### 请求机构

```typescript
// Router
export const appRouter = t.router({
  sayHello: t.procedure
    .meta({ openapi: { method: 'POST', path: '/say-hello/{name}' /* 👈 */ } })
    .input(z.object({ name: z.string() /* 👈 */, greeting: z.string() }))
    .output(z.object({ greeting: z.string() }))
    .mutation(({ input }) => {
      return { greeting: `${input.greeting} ${input.name}!` };
    });
});

// Client
const res = await fetch('http://localhost:3000/say-hello/Lily' /* 👈 */, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ greeting: 'Hello' }),
});
const body = await res.json(); /* { greeting: 'Hello Lily!' } */
```

### 自定义信头

任何自定义标题都可以在 `meta.openapi.requestHeaders` 财务报告和审定财务报表 `meta.openapi.responseHeaders` zod 对象计划, 这些标题将不会被验证 。 请考虑使用 [授权](https://npmcn.com/package/%40dokploy/trpc-openapi/#readme-authorization) 用于一等的 OpenAPI 认证/安全支持.

## HTTP 回复

状态代码将 `200` 以默认方式处理任何成功的请求。 如果出现错误,则状态代码将来自抛出 `TRPCError` 或退到 `500`。 。 。 .

您可以使用 `responseMeta` 函数.

请看 [此处错误状态代码](https://npmcn.com/package/%40dokploy/trpc-openapi/src/adapters/node-http/errors.ts)。 。 。 .

## 授权

要创建受保护的终点,请添加 `protect: true` 页:1 `meta.openapi` 每个 tRPC 程序的对象。 默认情况下,您可以使用 `createContext` 函数使用 `Authorization` 带有 `Bearer` 计划。 如果您想要使用不同的/ 附加方法( 如自定义信头或 cookie) 认证请求, 您可以通过指定来覆盖 `securitySchemes` 对象.

探索a [此处完整示例](https://npmcn.com/package/%40dokploy/trpc-openapi/examples/with-nextjs/src/server/router.ts)。 。 。 .

#### 服务器

```typescript
import { TRPCError, initTRPC } from '@trpc/server';
import { OpenApiMeta } from 'trpc-to-openapi';

type User = { id: string; name: string };

const users: User[] = [
  {
    id: 'usr_123',
    name: 'Lily',
  },
];

export type Context = { user: User | null };

export const createContext = async ({ req, res }): Promise<Context> => {
  let user: User | null = null;
  if (req.headers.authorization) {
    const userId = req.headers.authorization.split(' ')[1];
    user = users.find((_user) => _user.id === userId);
  }
  return { user };
};

const t = initTRPC.context<Context>().meta<OpenApiMeta>().create();

export const appRouter = t.router({
  sayHello: t.procedure
    .meta({ openapi: { method: 'GET', path: '/say-hello', protect: true /* 👈 */ } })
    .input(z.void()) // no input expected
    .output(z.object({ greeting: z.string() }))
    .query(({ input, ctx }) => {
      if (!ctx.user) {
        throw new TRPCError({ message: 'User not found', code: 'UNAUTHORIZED' });
      }
      return { greeting: `Hello ${ctx.user.name}!` };
    }),
});
```

#### 客户端

```typescript
const res = await fetch('http://localhost:3000/say-hello', {
  method: 'GET',
  headers: { Authorization: 'Bearer usr_123' } /* 👈 */,
});
const body = await res.json(); /* { greeting: 'Hello Lily!' } */
```

## 实例

_关于先进的使用案例,请在我们的 [完整的测试套件](https://npmcn.com/package/%40dokploy/trpc-openapi/test)。 。 。 ._

#### 有快车

请看 [此处完整示例](https://npmcn.com/package/%40dokploy/trpc-openapi/examples/with-express)。 。 。 .

```typescript
import { createExpressMiddleware } from '@trpc/server/adapters/express';
import express from 'express';
import { createOpenApiExpressMiddleware } from 'trpc-to-openapi';

import { appRouter } from '../appRouter';

const app = express();

app.use('/api/trpc', createExpressMiddleware({ router: appRouter }));
app.use('/api', createOpenApiExpressMiddleware({ router: appRouter })); /* 👈 */

app.listen(3000);
```

#### 用 Next.js 应用程序路由器

请看 [此处完整示例](https://npmcn.com/package/%40dokploy/trpc-openapi/examples/with-nextjs-appdir)。 。 。 .

```typescript
// src/app/[...trpc]/route.ts
import { appRouter } from '~/server/api/root';
import { createContext } from '~/server/api/trpc';
import { type NextRequest } from 'next/server';
import { createOpenApiFetchHandler } from 'trpc-to-openapi';

export const dynamic = 'force-dynamic';

const handler = (req: NextRequest) => {
  // Handle incoming OpenAPI requests
  return createOpenApiFetchHandler({
    endpoint: '/',
    router: appRouter,
    createContext: () => createContext(req),
    req,
  });
};

export {
  handler as GET,
  handler as POST,
  handler as PUT,
  handler as PATCH,
  handler as DELETE,
  handler as OPTIONS,
  handler as HEAD,
};
```

#### 使用 Next.js 页面路由器

请看 [此处完整示例](https://npmcn.com/package/%40dokploy/trpc-openapi/examples/with-nextjs)。 。 。 .

```typescript
// pages/api/[...trpc].ts
import { createOpenApiNextHandler } from 'trpc-to-openapi';

import { appRouter } from '../../server/appRouter';

export default createOpenApiNextHandler({ router: appRouter });
```

#### 使用快捷键

请看 [此处完整示例](https://npmcn.com/package/%40dokploy/trpc-openapi/examples/with-fastify)。 。 。 .

```typescript
import { fastifyTRPCPlugin } from '@trpc/server/adapters/fastify';
import Fastify from 'fastify';
import { fastifyTRPCOpenApiPlugin } from 'trpc-to-openapi';

import { appRouter } from './router';

const fastify = Fastify();

async function main() {
  await fastify.register(fastifyTRPCPlugin, { router: appRouter });
  await fastify.register(fastifyTRPCOpenApiPlugin, { router: appRouter }); /* 👈 */

  await fastify.listen({ port: 3000 });
}

main();
```

## 类型

#### 生成 OpenApi 文档选项

请看 [这里有完整的打字](https://npmcn.com/package/%40dokploy/trpc-openapi/src/generator/index.ts)。 。 。 .

| 财产 | 类型 | 说明 | 需求 |
| --- | --- | --- | --- |
| `title` | `string` | API名称. | `true` |
| `description` | `string` | API简介. | `false` |
| `version` | `string` | OpenAPI文档的版本. | `true` |
| `baseUrl` | `string` | 目标服务器的基础 URL . | `true` |
| `docsUrl` | `string` | 外部文档的 URL . | `false` |
| `tags` | `string[]` | 命令端点组的列表 . | `false` |
| `securitySchemes` | `Record<string, SecuritySchemeObject>` | 默认为 `Authorization` 标题带有 `Bearer` 计划 | `false` |
| `filter` | `(ctx: { metadata: { openapi: NonNullable<OpenApiMeta['openapi']> } & TMeta }) => boolean` | 可选过滤功能包含/排除生成的 OpenAPI 文档中的程序 . | `false` |

#### 打开 ApiMeta

请看 [这里有完整的打字](https://npmcn.com/package/%40dokploy/trpc-openapi/src/types.ts)。 。 。 .

| 财产 | 类型 | 说明 | 需求 | 默认 |
| --- | --- | --- | --- | --- |
| `enabled` | `boolean` | 将这一程序曝光到 `trpc-to-openapi` 适配器和 OpenAPI 文档. | `false` | `true` |
| `method` | `HttpMethod` | HTTP方法 此端点被曝光 。 值可以是 `GET`, (中文(简体) ), `POST`, (中文(简体) ), `PATCH`, (中文(简体) ), `PUT` 或者说 `DELETE`。 。 。 . | `true` | `undefined` |
| `path` | `string` | 此端点已打开路径名 。 数值必须从 `/`,使用 `{}`。 。 。 . | `true` | `undefined` |
| `protect` | `boolean` | 要求该端点使用安全计划. | `false` | `true` |
| `summary` | `string` | OpenAPI文档中包含的终点的简短摘要. | `false` | `undefined` |
| `description` | `string` | OpenAPI文档中包含的终点的动词描述. | `false` | `undefined` |
| `tags` | `string[]` | OpenAPI 文档中用于逻辑组合端点的标记列表. | `false` | `undefined` |
| `requestHeaders` | `AnyZodObject` | 一个 Zod 对象计划描述任何自定义头来添加到 OpenAPI 文档中此端点的请求. | `false` | `undefined` |
| `responseHeaders` | `AnyZodObject` | 一个 Zod 对象计划描述任何自定义头来添加到OpenAPI文档中这个端点的响应. | `false` | `undefined` |
| `successDescription` | `string` | 用于描述成功响应的字符串 . | `false` | `'Successful response'` |
| `errorResponses` | `number[] | { [key: number]: string }` | 列出错误响应代码或响应代码的对象及其描述,以加入这个端点的响应. | `false` | `undefined` |
| `contentTypes` | `OpenApiContentType[]` | OpenAPI 文档中指定的一组内容类型. | `false` | `['application/json']` |
| `deprecated` | `boolean` | 是否将一个终点标为已贬值 | `false` | `false` |

#### 创建 OpenApi 节点HttpHandler 选项

请看 [这里有完整的打字](https://npmcn.com/package/%40dokploy/trpc-openapi/src/adapters/node-http/core.ts)。 。 。 .

| 财产 | 类型 | 说明 | 需求 |
| --- | --- | --- | --- |
| `router` | `Router` | 您的应用程序 tRPC 路由器 . | `true` |
| `createContext` | `Function` | 传递背景( E)`ctx`向程序解决者提供数据. | `false` |
| `responseMeta` | `Function` | 返回对状态代码和标题的任何修改. | `false` |
| `onError` | `Function` | 处理器内出错时调用 . | `false` |
| `maxBodySize` | `number` | 以字节表示的最大请求体积( 默认: 100kb) . | `false` |

* * *

## 许可证

根据麻省理工学院的许可证分发。 更多信息见LICENSE.

**在 OpenAPI 输出中过滤程序**

你可以用这个 `filter` 选项,从生成的 OpenAPI 文档中选择性地包含或排除程序。 过滤器函数接收带有程序元数据的上下文对象. 返回时 `true` 包括程序,或 `false` 将它排除在外.

**示例**

```typescript
const appRouter = t.router({
  publicProc: t.procedure
    .meta({ openapi: { method: 'GET', path: '/public' }, isPublic: true })
    .input(z.object({}))
    .output(z.object({ result: z.string() }))
    .query(() => ({ result: 'public' })),
  privateProc: t.procedure
    .meta({ openapi: { method: 'GET', path: '/private' }, isPublic: false })
    .input(z.object({}))
    .output(z.object({ result: z.string() }))
    .query(() => ({ result: 'private' })),
});

// Only include procedures where isPublic is true
const openApiDocument = generateOpenApiDocument(appRouter, {
  ...defaultDocOpts,
  filter: ({ metadata }) => metadata.isPublic === true,
});

// openApiDocument.paths will only include '/public'
```

也可以通过一个元数据通用到 `generateOpenApiDocument` 获取过滤器函数中自定义元数据的适当类型:

```typescript
// Define your custom metadata type
interface MyMeta {
  isPublic: boolean;
}

const openApiDocument = generateOpenApiDocument<MyMeta>(appRouter, {
  ...defaultDocOpts,
  filter: ({ metadata }) => metadata.isPublic === true,
});
```

## 常见问题

### @dokploy/trpc-openapi 是什么？

tRPC 打开API

### 如何安装 @dokploy/trpc-openapi？

在项目目录运行 npm install @dokploy/trpc-openapi，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：@trpc/server（^11\.1\.0）、zod（^4\.3\.6）、zod-openapi（^5\.0\.1）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @dokploy/trpc-openapi 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @dokploy/trpc-openapi 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @dokploy/trpc-openapi 可以商用吗？

@dokploy/trpc-openapi 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @dokploy/trpc-openapi 的下载量有多少？

根据 npm 官方下载统计，@dokploy/trpc-openapi 在 2026/10/13 – 2026/11/11 这 30 天内被下载 15,273 次，日均约 509 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @dokploy/trpc-openapi 还在维护吗？

最新版本 0\.0\.19 发布于 2026/04/12（7 个月前）；至今共发布 20 个版本，其中过去 12 个月发布了 16 个；首次发布于 2024/06/24。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

