- AI 技能
- AI 插件
- 人工智能
【免费下载链接】agentic-awesome-skills
AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,600+ agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.
本文聚焦 AAS(agentic-awesome-skills)仓库内
api-patterns技能中的 tRPC 设计原则文档,系统梳理 tRPC 的适用场景、核心收益与集成方式,并结合同技能下的 API 风格决策树、版本管理策略与启发式校验脚本,给出可落地的 TypeScript 单仓库 API 设计实践。读完本文,你将能够判断一个项目是否适合 tRPC、如何在 REST/GraphQL/tRPC 之间做出选择,并理解类型安全与运行时校验的边界。
一、tRPC 原则文档定位:不复制模式,而是学会思考
在 AAS 仓库中,api-patterns是一个面向 API 设计决策的技能模块,其入口文件 SKILL.md 明确写道:"API design decisions tied to the consumers and deployment constraints. Learn to THINK, not copy fixed patterns."(API 设计决策要绑定消费方与部署约束;学会思考,而不是复制固定模式)。
本技能采用"选择性阅读规则"(Selective Reading Rule),维护了一张内容地图:
| 文件 | 说明 | 何时阅读 |
|---|---|---|
| api-style.md | REST vs GraphQL vs tRPC 决策树 | 选择 API 类型时 |
| rest.md | 资源命名、HTTP 方法、状态码 | 设计 REST API 时 |
| response.md | 信封模式、错误格式、分页 | 设计响应结构时 |
| graphql.md | Schema 设计、适用时机、安全性 | 考虑 GraphQL 时 |
| trpc.md | TypeScript 单仓库、类型安全 | TS 全栈项目时 |
| versioning.md | URI/Header/Query 版本管理 | API 演进规划时 |
| auth.md | JWT、OAuth、Passkey、API Keys | 认证模式选择时 |
| rate-limiting.md | 令牌桶、滑动窗口 | API 防护时 |
| documentation.md | OpenAPI/Swagger 最佳实践 | 文档化时 |
| security-testing.md | OWASP API Top 10、认证/授权测试 | 安全审计时 |
trpc.md 正是这张地图中针对TypeScript 全栈项目的一张专章:它不去罗列 tRPC 的全部 API,而是给出"何时该用、何时不该用、用它能得到什么、常见的集成拓扑"这四组判断依据,帮助开发者在具体约束下做选择。
二、何时使用 tRPC:完美契合与明显不适
原文档用一组清晰的对比清单给出适用性判断。完美契合的场景(Perfect fit):
✅ Perfect fit: ├── TypeScript on both ends 两端都是 TypeScript ├── Monorepo structure 单仓库(monorepo)结构 ├── Internal tools 内部工具 ├── Rapid development 快速迭代开发 └── Type safety critical 类型安全至关重要明显不合适的场景(Poor fit):
❌ Poor fit: ├── Non-TypeScript clients 非 TypeScript 客户端 ├── Public API 公开 API ├── Need REST conventions 需要 REST 约定 └── Multiple language backends 多语言后端逐条展开理解:
- 两端 TypeScript 是前提:tRPC 的端到端类型推断依赖前端与后端共享同一套 TypeScript 类型。只要有一端不是 TypeScript(例如 Swift/Java 原生客户端、Python 后端),类型收益就会大打折扣,此时应优先考虑 REST + OpenAPI。
- 单仓库是放大器:前后端代码同仓,才能直接
import type共享类型;如果前后端分仓部署、各自独立发布,构建期共享的类型无法保证线上已部署客户端与新版服务端仍然兼容(这一点原技能在 SKILL.md 的 Limitations 与 versioning.md 中反复强调)。 - 内部工具与快速迭代:没有公开契约的兼容性包袱、变更频繁、团队小步快跑,正是 tRPC 低摩擦特性的用武之地。
- 类型安全关键:当"改一处类型,全链路报错"的价值大于接口文档维护成本时,tRPC 优势明显。
反之,公开 API 需要面向未知的、多语言的外部消费方,REST + OpenAPI 的兼容面更宽;多语言后端则无法享受单一类型源带来的收益。
三、tRPC 的核心收益:从共享类型到全链路类型推断
原文档总结的五条收益,构成了 tRPC 的选型价值主张:
Why tRPC: ├── Shared TypeScript types; still validate untrusted runtime input │ 共享 TypeScript 类型;但依然要校验不可信的运行时输入 ├── End-to-end type inference │ 端到端类型推断 ├── IDE autocomplete across stack │ 跨栈 IDE 自动补全 ├── Type errors surface for clients rebuilt against the shared contract │ 针对共享契约重新构建的客户端会浮出类型错误 └── No code generation step │ 无需代码生成步骤这五条收益中,"共享类型≠安全"是最容易被误读的一点,也是本技能反复强调的核心认知:
- 类型只在编译期生效。tRPC 的类型推断把"前端调用签名"与"后端 procedure 定义"绑定在一起,前端重新构建时,接口变更会立刻表现为 TypeScript 编译错误——这是"共享契约"带来的构建期保护。
- 运行时输入永远不可信。HTTP 请求到达服务端时,任何字段都可能被篡改。因此 tRPC 生态通常搭配 zod 之类的 schema 校验库对输入做运行时验证。这一点可以直接在仓库的校验脚本中得到印证:api_validator.py 在
check_api_code中把zod、joi、yup、validate、schema、pydantic等关键词列为输入校验(Input validation)的判定模式——也就是说,tRPC 项目同样要求显式的输入校验证据,类型推断本身不算校验。 - tRPC 推断不强制执行授权与兼容性。原技能 SKILL.md 的 Limitations 明确写道:"GraphQL query shape, tRPC inference and HTTP method names do not enforce resource authorization or backwards compatibility."(GraphQL 查询形态、tRPC 类型推断与 HTTP 方法名都不会强制执行资源授权或向后兼容。)类型安全解决的是"编译期错配",而授权、限流、兼容性需要单独设计。
关于"无代码生成步骤"
相比 gRPC(需 protoc 生成桩代码)或部分 GraphQL 工具链(需 codegen),tRPC 通过 TypeScript 的类型推断直接把服务端 procedure 的类型推导到客户端,无需额外生成层。这降低了工具链复杂度,也是"快速开发"定位的重要来源。需要说明的是,"无需生成"不等于"没有契约"——契约就是两端共享的 TypeScript 类型本身。
四、常见集成模式:从 Next.js 到任意 TS 前端
原文档给出了四类常见集成拓扑:
Common setups: ├── Next.js + tRPC (most common) 最普遍 ├── Monorepo with shared types 单仓库 + 共享类型 ├── Remix + tRPC └── Any TS frontend + backend 任意 TS 前端 + 后端- Next.js + tRPC:tRPC 官方文档中覆盖最充分的组合,App Router 下的 server/client 边界与 tRPC 的 procedure 分层天然契合,是社区最常见的落地形态。
- Monorepo with shared types:这是 tRPC 最佳实践的核心形态——在单仓库中抽取一个共享类型包(通常是
@repo/validators或@repo/types),前端只import type,后端在 procedure 中输入输出引用同一类型源,实现"单一事实来源"。 - Remix + tRPC / 任意 TS 前端:tRPC 的客户端基于
createTRPCProxyClient的 fetch/HTTP 适配器,不绑定特定框架;只要是 TypeScript 前端,都可以通过 tRPC client 获得相同的类型推断收益。
无论哪种拓扑,都需要遵循本文第三节的原则:共享类型只覆盖编译期,procedure 内部依然要对输入做运行时校验、对操作做授权控制。
五、放进决策树:REST vs GraphQL vs tRPC
tRPC 不是银弹,它的位置由消费方形态决定。api-style.md 提供的决策树在"谁在使用 API"这一问题上给出了明确的路径:
Who are the API consumers? │ ├── Public API / Multiple platforms │ └── REST + OpenAPI (widest compatibility) │ ├── Complex data needs / Multiple frontends │ └── GraphQL (flexible queries) │ ├── TypeScript frontend + backend (monorepo) │ └── tRPC (end-to-end type safety) │ ├── Real-time / Event-driven │ └── WebSocket + AsyncAPI │ └── Internal microservices └── gRPC (performance) or REST (simplicity)即:当且仅当"TypeScript 前端 + 后端 + 单仓库"时,tRPC 才进入候选。同文档的三方对比表把这种差异量化:
| 因素 | REST | GraphQL | tRPC |
|---|---|---|---|
| 最适合 | 公开 API | 复杂应用 | TS 单仓库 |
| 学习曲线 | 低 | 中 | 低(若熟悉 TS) |
| 过取/欠取(over/under fetching) | 为消费方定制端点形态 | 客户端自选字段,需强制成本限制 | 取决于 procedure 设计 |
| 类型安全 | 手动(OpenAPI) | 基于 Schema | 自动 |
| 缓存 | HTTP 原生 | 复杂 | 基于客户端 |
值得注意 tRPC 一栏的两条:"过取/欠取取决于 procedure 设计"与"缓存基于客户端"。tRPC 没有 GraphQL 的字段选择能力,也没有 REST 的 HTTP 缓存语义(如 GET 的 ETag/304),因此:
- 若要避免过度取数,需要在后端设计粒度合适的 procedure(细粒度查询 + 组合),这是 API 设计者的职责,类型推断不会替你解决;
- 缓存策略需要自行设计(如
trpc-panel、浏览器 HTTP 缓存、React Query 的客户端缓存等)。
选择前建议回答 api-style.md 给出的五个筛选问题:
- 谁在消费这个 API?
- 前端是 TypeScript 吗?
- 数据关系有多复杂?
- 缓存是否关键?
- 是公开 API 还是内部 API?
只要第 2、5 题分别回答"是"与"内部",第 1、3、4 题的答案通常都会把天平推向 tRPC。
六、tRPC 与版本管理:类型只保证构建期
tRPC 项目同样面临 API 演进问题,而版本管理的哲学在此有特殊性。versioning.md 给出的四种策略各有取舍:
| 策略 | 实现 | 权衡 |
|---|---|---|
| URI | /v1/users | 清晰、易缓存 |
| Header | Accept-Version: 1 | URL 更干净、但难以发现 |
| Query | ?version=1 | 易添加、但混乱 |
| 无 | 谨慎演进 | 内部最佳,公开有风险 |
其中与 tRPC 直接相关的一条哲学是:
tRPC? → Test deployed-client compatibility; types only help at build time 测试已部署客户端的兼容性;类型只在构建期起作用这是 tRPC 版本管理的关键提醒:类型系统无法保护已经部署到线上的旧客户端。当你在单仓库中修改了一个 procedure 的输入输出类型,本地前端重新构建会立即报错——但线上仍然在跑旧版本前端的用户不会得到任何编译期保护。因此:
- 内部快速迭代时,可以不做显式版本号,靠"谨慎演进"(只做向后兼容的加法式变更);
- 但只要存在独立部署、独立发布节奏的客户端,就应该考虑 URI 版本化,并对已部署客户端的兼容性做真实测试,而不是依赖
tsc通过就放行。
七、决策清单与反模式:把 tRPC 选型纳入完整流程
SKILL.md 提供了在设计任何 API(含 tRPC)之前应完成的决策清单:
- 是否询问了 API 消费方?
- 是否为当前上下文选择了 API 风格(REST/GraphQL/tRPC)?
- 是否定义了统一的响应格式?
- 是否规划了版本化策略?
- 是否考虑了认证需求?
- 是否规划了限流?
- 是否确定了文档化方案?
同时要避开反模式(Anti-Patterns):
不要做(DON'T):
- 对一切场景默认使用 REST;
- 在 REST 端点中使用动词(如
/getUsers); - 返回不一致的响应格式;
- 向客户端暴露内部错误;
- 跳过限流。
应当做(DO):
- 基于上下文选择 API 风格;
- 询问客户端需求;
- 充分文档化;
- 使用恰当的状态码。
把这些映射到 tRPC 项目上:即便你选定了 tRPC,依然要定义统一错误格式(如 tRPC 的 error formatter)、规划 procedure 的认证(中间件)与限流、并保证输入校验(zod)到位——tRPC 只是替换了"契约传输层",它没有替你完成其余六项 API 工程责任。
八、用仓库校验脚本做实现后的自查
原技能还附带了一个本地启发式扫描脚本 scripts/api_validator.py,运行方式为:
python3 skills/api-patterns/scripts/api_validator.py <project_path>脚本会从目标项目中发现 API 相关文件(*api*.ts/js/py、routes/、controllers/、endpoints/、openapi.json/yaml、swagger等,最多采样 15 个文件,并排除node_modules、.git、dist、build、__pycache__),随后用正则做浅层检查:
- 错误处理:
try {、.catch(、except、catch(; - 状态码:
status(3xx)、HttpStatus.、res.status(等; - 输入校验:
validate、schema、zod、joi、yup、pydantic、@Body(、@Query(; - 认证/授权:
auth、jwt、bearer、token、middleware、guard; - 限流:
rateLimit、throttle; - 日志:
console.log、logger.、log.。
必须明确脚本的边界:正如脚本头注释所写,它是 "Heuristic triage"(启发式分流),不是 schema 验证,更不是安全审计或部署审批。对一个 tRPC 项目而言,脚本在"输入校验"一栏能否命中zod模式,恰好可以作为"你是否真的对 procedure 输入做了运行时校验"的快速佐证——但[OK]只代表正则命中,不代表校验逻辑正确。SKILL.md 的 Limitations 也提醒:限流无法单独防止所有资源耗尽(还需考虑大小、并发、时间与供应商成本边界);安全类检查只能在授权范围内对本地/测试目标进行。
九、结语:tRPC 是"契约策略",不是"安全策略"
AAS 的 trpc.md 用一份精炼的原则清单回答了三个问题:何时用(TS 两端 + 单仓库 + 内部 + 快迭代 + 类型安全关键)、为何用(共享类型 + 端到端推断 + 无 codegen)、怎么集成(Next.js/单仓库/Remix/任意 TS 前端)。而把它放回api-patterns技能整体来看,结论会更加完整:
- tRPC 解决契约层问题:它让前后端共享的 TypeScript 类型成为单一事实来源,把接口错配提前到编译期;
- 类型安全 ≠ 输入安全:运行时校验(zod 等)与授权控制是强制义务,tRPC 推断本身不提供;
- 构建期 ≠ 生产期:已部署客户端的兼容性需要显式测试与版本策略,不能依赖
tsc; - 选型先问消费方:公开 API 选 REST + OpenAPI、复杂查询多前端选 GraphQL、TS 全栈单仓库选 tRPC,决策树与对比表是判断依据。
最终回归技能入口的那句话:学会思考,而不是复制固定模式。tRPC 原则文档提供的正是这种"在约束下做选择"的思考框架——类型推断帮你把契约钉死在两端,而其余 API 工程责任(校验、授权、限流、版本、文档)依然需要你逐项落实。
- AI 技能
- AI 插件
- 人工智能
【免费下载链接】agentic-awesome-skills
AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,600+ agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.
相关推荐
如何用Next.js与TRPC构建端到端类型安全API:完整指南
如何用Next.js与TRPC构建端到端类型安全API:完整指南 Next.js作为React框架的佼佼者,为开发者提供了构建全栈应用的强大能力。而TRPC(T
前端Web框架SSR后端tRPC-Nuxt:构建端到端类型安全的API
tRPC Nuxt:构建端到端类型安全的API 项目介绍 tRPC Nuxt 是一个专为 Nuxt 应用程序设计的开源项目,旨在通过 tRPC.io https
TypeScript与TRPC终极指南:构建端到端类型安全API的完整教程
TypeScript与TRPC终极指南:构建端到端类型安全API的完整教程 TypeScript作为现代前端开发的标配,与TRPC框架的完美结合,为开发者提供了
文档教程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考