tRPC 技能决策树与端到端最小应用实战:trpc-router SKILL 导读
2026/9/10 7:31:14 网站建设 项目流程

tRPC 技能决策树与端到端最小应用实战:trpc-router SKILL 导读

【免费下载链接】trpc🧙‍♀️ Move Fast and Break Nothing. End-to-end typesafe APIs made easy.项目地址: https://gitcode.com/GitHub_Trending/tr/trpc

导读

本文围绕 tRPC 仓库packages/server/skills/trpc-router/SKILL.md这份「技能路由」(Skill Router)文档展开,它不直接教你某一项 tRPC 功能,而是为开发者提供一个按任务分流的决策树:你要做服务端、还是宿主适配器、还是客户端、还是接入框架,分别该加载哪份专项技能文档。同时它给出了一份最小可运行应用的端到端代码骨架(server/trpc.ts → appRouter → standalone 服务器 → 客户端)。读完本文,你将能快速判断自己当前任务属于 tRPC 的哪个环节、该查阅哪个专项 SKILL,并据此在一分钟内搭出第一个类型安全的 query/mutation 应用。


这份文档的定位:全部 tRPC 技能的入口

trpc-router/SKILL.md 是整个 tRPC 技能体系的入口文档(front matter 中标注type: corelibrary: trpclibrary_version: '11.16.0'),其description明确说明:它是所有 tRPC skills 的入口,按任务做决策路由——initTRPC.create()t.router()t.procedurecreateTRPCClient、适配器、订阅、React Query、Next.js、links、中间件、校验器、错误处理、缓存、FormData 均被覆盖。其官方素材来源为 introduction.mdx 与 quickstart.mdx(见 front matter 的sources)。

因此它是一张「地图」,而同目录下的server-setupmiddlewaresvalidatorserror-handling等 15 份 SKILL 才是各自的「城市导游」。使用范式是:先经本决策树定位,再加载对应专项技能

决策树全景:按「你正在做什么」导航

SKILL.md 的核心是一棵以问题为导向的决策树,本节逐层展开并标注每条分支应加载的专项技能文件(均位于packages/server/skills/目录下)。

分支一:定义 tRPC 后端(服务端)

你在做的事加载的技能
初始化 tRPC、定义 routers / procedures / context、导出AppRouterserver-setup→ server-setup/SKILL.md
添加中间件(.use)、鉴权守卫、日志、基础 proceduremiddlewares→ middlewares/SKILL.md
使用 Zod 等库做输入/输出校验validators→ validators/SKILL.md
抛出类型化错误、为客户端格式化错误、全局错误处理error-handling→ error-handling/SKILL.md
在服务端代码中调用 procedure、编写集成测试server-side-calls→ server-side-calls/SKILL.md
在 query 响应上设置 Cache-Control 头(CDN / 浏览器缓存)caching→ caching/SKILL.md
在 mutation 中接收 FormData、File、Blob 或二进制上传non-json-content-types→ non-json-content-types/SKILL.md
搭建实时订阅(SSE 或 WebSocket)subscriptions→ subscriptions/SKILL.md

分支二:宿主 tRPC API(适配器)

你在做的事加载的技能
Node.js 内置 HTTP 服务器(最简单,适合本地开发)adapter-standalone→ adapter-standalone/SKILL.md
Express 中间件adapter-express→ adapter-express/SKILL.md
Fastify 插件adapter-fastify→ adapter-fastify/SKILL.md
AWS Lambda(API Gateway v1/v2、Function URLs)adapter-aws-lambda→ adapter-aws-lambda/SKILL.md
Fetch API / Edge(Cloudflare Workers、Deno、Vercel Edge、Astro、Remix)adapter-fetch→ adapter-fetch/SKILL.md

对应源码位于 packages/server/src/adapters/,每类宿主均有独立实现文件与文档中成对出现的 example(如 examples/express-minimal、examples/cloudflare-workers、examples/lambda-url 等),便于对照学习。

分支三:消费 tRPC API(客户端)

你在做的事加载的技能
创建 vanilla TypeScript 客户端,配置 links、headers、类型client-setup→ client-setup/SKILL.md
配置 link 链(batching、streaming、split、WebSocket、SSE)links→ links/SKILL.md
用 SuperJSON transformer 支持 Date、Map、Set、BigIntsuperjson→ superjson/SKILL.md

分支四:与框架配合使用

你在做的事加载的技能
React + TanStack Query(useQuery、useMutation、queryOptions)react-query-setup→ react-query-setup/SKILL.md
Next.js App Router(RSC、Server Components、HydrateClient)nextjs-app-router→ nextjs-app-router/SKILL.md
Next.js Pages Router(withTRPC、SSR、SSG helpers)nextjs-pages-router→ nextjs-pages-router/SKILL.md

分支五:进阶模式

你在做的事加载的技能
从 tRPC router 生成 OpenAPI 规范与 REST 客户端openapi→ openapi/SKILL.md
多服务网关、自定义路由 link、SOA(面向服务架构)service-oriented-architecture→ service-oriented-architecture/SKILL.md
鉴权中间件 + 客户端 headers + 订阅鉴权auth→ auth/SKILL.md

使用技巧:多数任务并非单一分支。例如「搭建一个带鉴权、走 Express 的 React 全栈应用」,决策路径是server-setup → middlewares → adapter-express → react-query-setup,一次定位后按顺序加载即可。

Quick Reference:最小可运行应用逐段拆解

SKILL.md 的「Quick Reference: Minimal Working App」章节给出了从零到可调用的四段代码。这里逐段还原,并结合仓库中 examples/minimal 的真实工程进一步说明其运行语义。

第 1 段:初始化根对象(server/trpc.ts)

// server/trpc.ts import { initTRPC } from '@trpc/server'; const t = initTRPC.create(); export const router = t.router; export const publicProcedure = t.procedure;

这里initTRPC@trpc/server导出的单例构造器。查看 initTRPC.ts,其定义是export const initTRPC = new TRPCBuilder()——一个可链式调用的类型构造器,create()是终结操作,返回带有proceduremiddlewareroutermergeRouterscreateCallerFactory五个成员的根对象(同文件 L180-L213)。

值得注意的实践约束:

  • 整个后端只调用一次initTRPC.create()。examples/minimal/src/server/trpc.ts 中的注释「Initialization of tRPC backend, Should be done only once per backend!」即这一约定,随后将routerpublicProcedure重新导出,供各路由文件复用。
  • 若需要自定义 context / meta / transformer,可在create()前链式调用.context<T>().meta<T>(),或在create(opts)传入RuntimeConfigOptions。从 initTRPC.ts 可见支持的运行期选项包括transformer(数据序列化,默认defaultTransformer)、errorFormatterisDev(默认按NODE_ENV !== 'production'推断)、allowOutsideOfServerdefaultMetaisServer。其中allowOutsideOfServer默认false,若在非服务端环境调用会直接抛错(同文件 L174-L179),这是为了防止把 tRPC 服务端代码误引入客户端 bundle。

第 2 段:定义 AppRouter(server/appRouter.ts)

// server/appRouter.ts import { z } from 'zod'; import { publicProcedure, router } from './trpc'; export const appRouter = router({ hello: publicProcedure .input(z.object({ name: z.string() })) .query(({ input }) => ({ greeting: `Hello ${input.name}` })), }); export type AppRouter = typeof appRouter;

要点:

  1. procedure 分为 query / mutation / subscription 三种类型。客户端侧的调用方法由类型自动推导:query 对应.query()、mutation 对应.mutate()、subscription 对应.subscribe()——这一点可在 createTRPCClient.ts 的DecorateProcedure类型映射中得到源码级印证。
  2. 输入校验用.input(z.object(...)),运行时由 Zod schema 把关,类型层面则被自动推导进 resolver 的{ input }参数。
  3. export type AppRouter = typeof appRouter;是类型安全的枢纽:它只导出类型而不导出值,从而可以安全地在前端 import 而不会把服务端代码带进客户端 bundle(这也是官方推荐的约定)。

真实的更完整形态可参考 examples/minimal/src/server/index.ts:其中路由被组织为嵌套命名空间(user.listuser.byIduser.createexamples.iterable),演示了 input 驱动的 query、含 body 的 mutation,以及 async generator 实现的流式 iterable——可见 router 对象天然支持任意嵌套结构,路径即 key 的层级组合。

第 3 段:用 standalone 适配器启动服务(server/index.ts)

// server/index.ts import { createHTTPServer } from '@trpc/server/adapters/standalone'; import { appRouter } from './appRouter'; const server = createHTTPServer({ router: appRouter }); server.listen(3000);

createHTTPServer由 standalone.ts 实现:它本质上是http.createServer(createHTTPHandler(opts))的封装——先由createHTTPHandler把 tRPC 请求处理逻辑包成 Node 标准的RequestListener,再交给 Node 内置http模块。在 examples/minimal/src/server/index.ts 中可以看到完全一致的使用方式,这也是官方标注「最简单、适合本地开发」的宿主选择。

适配器可配置项(同文件 L30-L44)值得留意:

  • router:必填的 AppRouter 实例。
  • basePath:请求路径前缀,默认'/',会被从请求 pathname 头部切掉,例如设为'/trpc/'后所有请求都从/trpc/<procedurePath>进入。该逻辑见 standalone.ts 中basePath ?? '/'pathname.slice(sliceLength)
  • 同时透传node-http层的所有选项,如createContext(按请求构建 context)、middlewarebatchingmaxBodySize、响应头自定义等。
  • 文件同样导出了createHTTP2Handler(同文件 L119-L120),面向需要 HTTP/2 的场景。

第 4 段:创建类型安全客户端(client/index.ts)

// client/index.ts import { createTRPCClient, httpBatchLink } from '@trpc/client'; import type { AppRouter } from '../server/appRouter'; const trpc = createTRPCClient<AppRouter>({ links: [httpBatchLink({ url: 'http://localhost:3000' })], }); const result = await trpc.hello.query({ name: 'World' });

两个值得展开的细节:

  1. createTRPCClient<AppRouter>的类型魔法:查看 createTRPCClient.ts 可知,其内部基于TRPCUntypedClient之上套了双层 Proxy(createFlatProxy+createRecursiveProxy,同文件 L144-L151),把trpc.hello.query(...)这种链式路径在运行时拆成path = 'hello'type = 'query'后转发给底层客户端;而在编译期,TRPCClient<TRouter>会把AppRouter的每个叶子 procedure 精确装饰为query/mutate/subscribe方法并推断出各自的 input/output 类型。入参写错或返回类型不匹配都会在编辑器里直接报红——这就是「端到端类型安全」的实现基础。
  2. httpBatchLink默认开启请求批处理:多个在同一事件循环 tick 内发起的 query 会合并成一个 HTTP 请求(通过dataLoader实现,见 httpBatchLink.ts),从而减少网络往返。其配置项包括url(必填)、headers(对象或函数)、transformer,以及maxURLLength/maxItems(默认均为Infinity,用于在 URL 过长或批次数超限时自动拆分请求,见同文件 L25-L26 与 L33-L53 的validate逻辑)。同时注意:该 link不支持 subscription,一旦收到 subscription 操作会直接抛出「Subscriptions are unsupported byhttpLink- usehttpSubscriptionLinkorwsLink」的错误(同文件 L96-L99)。

何时不需要这份决策树:任务与技能的快速对应表

把决策树压缩成一张速查表,可帮助 Agent 与开发者以更少跳转命中目标技能:

任务关键词首选技能仓库路径
初始化 / router / procedure / contextserver-setuppackages/server/skills/server-setup/
middleware / 鉴权 / 日志middlewarespackages/server/skills/middlewares/
Zod / 输入校验validatorspackages/server/skills/validators/
错误 / 格式化error-handlingpackages/server/skills/error-handling/
caller / 测试server-side-callspackages/server/skills/server-side-calls/
Cache-Controlcachingpackages/server/skills/caching/
FormData / 上传non-json-content-typespackages/server/skills/non-json-content-types/
SSE / WebSocketsubscriptionspackages/server/skills/subscriptions/
standalone / express / fastify / lambda / fetch 宿主adapter-* 系列packages/server/skills/adapter-*/
创建客户端 / links / transformerclient-setup / links / superjsonpackages/client/skills/*/
React + TanStack Queryreact-query-setuppackages/tanstack-react-query/skills/react-query-setup/
Next.js App / Pages Routernextjs-app-router / nextjs-pages-routerpackages/next/skills/*/
OpenAPI 生成openapipackages/openapi/skills/openapi/
多服务 / SOAservice-oriented-architecturepackages/server/skills/service-oriented-architecture/

从决策树走向真实工程:下一步实践建议

有了上面的地图与最小骨架,建议按以下路径把「能跑」升级为「能上生产」:

  1. 先跑通最小应用:参照 examples/minimal(内含server/trpc.tsserver/index.tsserver/db.ts与类型共享的shared/transformer.ts),或直接套用本 SKILL 的四段代码。
  2. 按需补 context 与 middleware:加载server-setupmiddlewares两份 SKILL,把鉴权、日志、租户隔离等横切逻辑收敛进基础 procedure。
  3. 为每个路由对象套上校验:在.input()处定义 Zod schema(更复杂输入可参考validators中多 schema 组合的用法)。
  4. 挑选符合部署形态的宿主:本地/内部用 standalone;对外服务按平台选 express、fastify、lambda 或 fetch 适配器,各 SKILL 目录与其在 examples 中的同名示例一一对应,可直接对照。
  5. 把 transformer、错误格式化等跨端选项固化:在initTRPC.create({ transformer, errorFormatter })中统一声明,服务端与客户端两侧需保持一致。

See Also:配套技能直达

SKILL.md 结尾给出的配套技能均可在仓库内直接查看:

  • server-setup—— 完整的服务端初始化细节:server-setup/SKILL.md
  • client-setup—— 完整的客户端配置:client-setup/SKILL.md
  • adapter-standalone—— 上手最快的适配器:adapter-standalone/SKILL.md
  • react-query-setup—— React 集成:react-query-setup/SKILL.md
  • nextjs-app-router—— Next.js App Router 集成:nextjs-app-router/SKILL.md

官方文档(也是该 SKILL 的sources)同样在仓库内可查阅:introduction.mdx 与 quickstart.mdx。想要真正理解这份决策树为何如此划分,可进一步对照服务端核心实现 initTRPC.ts、客户端代理机制 createTRPCClient.ts 与批处理链路 httpBatchLink.ts,三者恰好构成「路由对象 → 类型推导客户端 → 高效传输」的完整闭环。

【免费下载链接】trpc🧙‍♀️ Move Fast and Break Nothing. End-to-end typesafe APIs made easy.项目地址: https://gitcode.com/GitHub_Trending/tr/trpc

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询