tRPC通信
在构建前后端分离或全栈 TypeScript 应用时,我们经常需要维护 API 类型定义、DTO、接口文档等内容。而一旦前后端协作中某个字段改了、类型不一致,就会带来一连串的维护成本。
有没有一种方式,让我们在后端写一个函数,前端就可以直接调用它,并自动享受类型提示和校验?这正是 tRPC 想要解决的问题。
是什么
**tRPC**(TypeScript Remote Procedure Call)是一个用于构建 类型安全 API 的框架,它允许你在 没有代码生成、没有手动同步类型定义 的前提下,直接在前后端共享类型,并像调用本地函数一样调用远端接口。
简单来说,就是用 TypeScript 写后端函数,前端像调用本地函数一样调用它,同时可以享受完整的类型提示。
方案优点
传统方案(REST / GraphQL):
- 类型定义需要手动维护或用代码生成
- 需要维护接口文档(如 Swagger)
- API 请求参数与返回类型解耦,容易出错
而 tRPC 提供了一个新范式:
- 类型自动推导,前后端 100% 类型一致
- 零代码生成,零配置即可使用
- 轻量高效,基于函数调用模型
- 与 Next.js、Express 等无缝集成
原理简述
tRPC 的基本模式是:
- 后端定义一个“路由”(其实是函数集合)
- 前端通过
createTRPCClient创建客户端 - 调用路由中的函数,就像在调用本地方法
tRPC 会自动处理:
- 参数校验
- 类型推导
- 异步通信
- 结果反序列化(支持如
Date等复杂类型)
使用实例
安装依赖
1 | npm install @trpc/server @trpc/client zod superjson |
通常搭配 Zod 做参数校验,SuperJSON 负责序列化复杂类型。
创建 tRPC 后端路由
以 Next.js 为例
1 | // server/router.ts |
API 处理器
以 Next.js 为例
1 | // pages/api/trpc/[trpc].ts |
客户端调用
使用 SuperJSON 处理
1 | // utils/trpc.ts |
调用方式:
1 | const result = await trpc.hello.query({ name: 'Allen' }) |
这里 SuperJSON 的作用:
默认 JSON 无法正确传输如 Date, BigInt, Map, undefined 等复杂类型。
tRPC 默认集成了 SuperJSON,用于序列化这些特殊数据结构,确保:
- 时间仍是
Date - 大整数不会被截断
- 错误对象结构完整
- 在 Redis、本地缓存、服务端传输中都能保持数据一致性
应用场景
- 构建全栈 TypeScript 应用(React + Next.js + tRPC)
- API 类型严格校验,无需写接口文档
- 快速开发原型或 MVP 项目
- 后端逻辑暴露给前端进行复用测试
| 特性 | REST | GraphQL | tRPC |
|---|---|---|---|
| 类型共享 | ❌ 手动 / 生成 | ⚠️ 需生成 | ✅ 自动 |
| 类型推导 | ❌ | 部分支持 | ✅ |
| 使用复杂类型 | ❌ | ⚠️ 需自定义标量 | ✅(默认支持) |
| 代码生成 | ❌ / ⚠️ | ✅ 推荐 | ❌ 不需要 |
| 使用难度 | 中 | 高 | 低 |
| 使用场景 | 任意 | API 聚合 | TypeScript 项目最佳 |
小结
tRPC 是现代 TypeScript 项目的理想选择,尤其适合使用 Next.js、React、Zustand、Prisma 等技术栈 的开发者。它不仅能提升开发效率,还能显著减少前后端沟通成本。 SuperJSON 的加入,让 tRPC 通信在处理复杂数据结构时更加健壮可靠。