惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Attack and Defense Labs
Attack and Defense Labs
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Recent Announcements
Recent Announcements
博客园 - 【当耐特】
博客园 - 三生石上(FineUI控件)
量子位
aimingoo的专栏
aimingoo的专栏
V
V2EX
Vercel News
Vercel News
B
Blog
M
MIT News - Artificial intelligence
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Hacker News: Ask HN
Hacker News: Ask HN
TaoSecurity Blog
TaoSecurity Blog
N
News and Events Feed by Topic
D
DataBreaches.Net
Blog — PlanetScale
Blog — PlanetScale
S
Secure Thoughts
U
Unit 42
博客园 - 叶小钗
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Hacker News - Newest:
Hacker News - Newest: "LLM"
N
News | PayPal Newsroom
Help Net Security
Help Net Security
S
Security Affairs
Microsoft Security Blog
Microsoft Security Blog
W
WeLiveSecurity
博客园 - Franky
Forbes - Security
Forbes - Security
Microsoft Azure Blog
Microsoft Azure Blog
博客园_首页
Schneier on Security
Schneier on Security
I
InfoQ
B
Blog RSS Feed
大猫的无限游戏
大猫的无限游戏
A
About on SuperTechFans
Webroot Blog
Webroot Blog
AWS News Blog
AWS News Blog
Last Week in AI
Last Week in AI
Security Archives - TechRepublic
Security Archives - TechRepublic
C
CERT Recently Published Vulnerability Notes
N
News and Events Feed by Topic
阮一峰的网络日志
阮一峰的网络日志
L
Lohrmann on Cybersecurity
SecWiki News
SecWiki News
Recent Commits to openclaw:main
Recent Commits to openclaw:main
J
Java Code Geeks

InfoQ - 促进软件开发领域知识与创新的传播

Meta 收购 Manus 这事儿泡汤了 5.5万 Star 开源项目 Ghostty 被迫出走,GitHub 正在终结一代技术人的乌托邦 谷歌开源“Agent Skill 超级工具箱”,云、库、引擎、AI全线打通,开发者狂喜 Slack 长时运行多智能体系统的上下文管理方案 从 T+1 到分钟级:金城银行基于 Apache Doris 构建高可靠、强一致的实时数据平台 谷歌云推出 Agents CLI,简化 AI 智能体开发全流程 Claude官方击穿高薪、高学历的安全防线!Anthropic点名10大高危职业,但有群人暂时稳了 亚马逊云科技终止 WorkMail 服务,并将 App Runner 转入维护模式 OPPO小布记忆:全模态碎片化内容的理解与智能整理实践|AICon上海 模力工场038周AI应用周榜:工具在消失,工作流在出现 Akamai CEO Tom Leighton:Agent 时代来临,云基础设施正从“中心化”转向“分布式边缘” 日均数百亿入库背后:从“人肉调度”到K8s弹性架构,度小满金融基于OceanBase重构入库架构实践 百度文库网盘发布GenFlow 4.0:月活用户超1亿,要把网盘变成全端AI工作台 Altman 投的 Agent 终端 Warp 开源了!斩获3.5万star 哪些客户需要拒, 敢让龙虾决定吗?_AI&大模型_InfoQ 中文站_InfoQ精选视频 从开发到生产:为什么越来越多的机器学习团队纷纷迁移到 Snowflake | BUILD 2025_AI&大模型_王玮_InfoQ精选视频 探索多智能体工作流:LangGraph Snowflake Cortex AI | BUILD 2025_AI&大模型_王玮_InfoQ精选视频 腾讯云分布式缓存数据库:AI Agent - 从提示词工程到 Harness 工程 | 腾讯云数据库 DBTalk_腾讯_凌敏_InfoQ精选视频 基于 Streamlit 为 CSV 数据构建分析智能体 | BUILD 2025_AI&大模型_王玮_InfoQ精选视频 AI 智能体:告别文档缺漏 | BUILD 2025_AI&大模型_王玮_InfoQ精选视频 构建 AI 驱动的数据管道:深度探讨 Snowflake Openflow 与非结构化数据 | BUILD 2025_AI&大模型_王玮_InfoQ精选视频 云端太贵、本地不够聪明,英特尔押注“端云混合AI”:智能体PC会替人完成工作 不到10%的存储投入,可能拖垮90%的GPU投资!IBM把AI Agent塞进存储系统,算清企业最容易忽略的一笔账 Snowpark 上手实战 | BUILD 2025_大数据_王玮_InfoQ精选视频 ClickHouse + Langfuse,构建 Agent 可观测基石 腾讯云分布式缓存数据库:Cluster Proxy 共享连接架构深度解析 | 腾讯云数据库 DBTalk_腾讯_凌敏_InfoQ精选视频 AI 写代码太烧钱了:Copilot、Claude 一起涨价,不如把程序员请回来? 英特尔发布至强600系列工作站处理器与锐炫Pro B70 GPU,全新AI工作站来了 腾讯云分布式缓存数据库:从 Redis 到 Valkey - 开源社区如何快速创新 | 腾讯云数据库 DBTalk_腾讯_凌敏_InfoQ精选视频 印奇这次要“从0重做”智驾模型!首谈阶跃和千里双公司布局:中国AI商业闭环要靠车跑出来 从Cursor返聘归来,90后华裔女高管带Claude开启日更模式:token成本比工程师工资低多了! 从 Coding 到 Agent:QCon 北京 2026 全景复盘,优秀出品人 & 明星讲师名单揭晓 全链路支撑大模型国产化“Day 0适配”,商汤大装置构建全栈能力底座 凌晨,OpenAI 与亚马逊云科技史上最大联合发布来了 HashiCorp Vault 2.0 发布:引入新身份联邦机制,迈入 IBM 生命周期体系 Yelp 实现超 1,000 个 Cassandra 节点零停机升级 写了 17 年开源代码,我为什么认为 Coding Agents 堆功能是在瞎折腾? 基于 Apache Camel 编排智能体与多模态 AI 管道 面向智能体与人类用户的AI记忆系统:架构设计与核心场景实践|AICon上海 Anthropic 推出 Managed Agents,简化 AI 代理部署流程 阿里HappyHorse开启灰测,720P视频生成低至0.44元/秒 讯飞联合清华团队押注量子AI:不看营收、不设KPI,一群“无人区”科学家,抢夺下代AI算力入口 小米万亿模型全面开源:MIT 协议、1M 上下文,但还是打不过 DeepSeek Cortex Code 入门指南:面向数据工程师的实践路径 | 技术实践 openJiuwen社区首发Team Skills,定义Coordination Engineering新范式 用 Snowflake Cortex Agents 释放结构化数据的最大价值 | 技术实践 Grafana 利用 Kafka 对 Loki 进行了架构重构,并发布了一款命令行工具,旨在将可观测性引入编码代理 ClickHouse重构全文索引:对象存储上跑出高性能 Full-Text Search 可观测性和遥测技术如何提升软件工程实践 Dropbox 与 GitHub 合作,将单体库大小从 87GB 缩减至 20GB Agent 的下一站:基于长期记忆系统 EverOS 的自我演进|AICon上海 同一赛道,四种收费:Agent 控制层(Harness)开始分裂 Cloudflare Sandboxes 正式发布,为 AI 代理提供持久化隔离环境 Agent 的“记忆断片”困局,该怎么破?_AI&大模型_AICon 全球人工智能开发与应用大会_InfoQ精选视频 数据分析师如何快速建立在 AI 时代最值钱的能力:一份可落地的行动路线图 摩尔线程最新财报:研发占比超86%,万卡级大规模智算集群落地 当云区域失效:地缘动荡环境下的高可用重构 Slack 重构通知系统,设置参与度提升 5 倍 智能体工程的隐性技术债务 “我把所有模型都换成了DeepSeek V4”:月账单将降 90%,效果还更好 阿里云智能集团高级技术专家刘少伟已确认出席AICon上海站,并分享如何构建企业 Agent 的自动化行动架构 Anthropic推出面向Claude Code的基于智能体的代码审查功能 北京车展直击:斑马智能甩出车载Agent短剧,比亚迪率先落地,AI让智能座舱又热起来了 Snowflake 作为智能体运行时:从静态管道迈向自主数据系统 | 技术实践 Snowflake 上的本体体系:基于 Cortex Code 能力实现从架构到部署 | 技术实践 Cloudflare 公布 MCP 架构方案,应对企业面临的安全与治理风险 复杂的项目管理怎么做到「AI 友好」?飞书项目用「开放」给出答案 Snowflake Cortex Code 的规范驱动开发:将 SDLC 方法论引入 AI 辅助工作流 | 技术实践 Copilot 不让注册了:从“随便用”到“全面限”,agent 把原有订价模型顶穿了 当互联网用AI卷效率时,这家公司先问了一连串“能不能” Meta 开始记录员工每一次点击:AI 要接管工作,先监控会工作的人 Meta“Token榜”逼疯打工人,一夜烧掉公司几万刀!AI时代Token焦虑越来越离谱 智源FlagOS完成DeepSeek-V4-Flash在八款芯片Day0适配,实现三重技术突破 DeepSeek V4 重磅开源!首次打通华为Ascend,也没丢掉英伟达,百万上下文夺回国产模型话语权 李志飞的“新实验”:当超级个体撞上真实组织 GPT-5.5 登顶时刻,Anthropic 亲口承认 Claude 变笨了!网友群嘲:太敷衍 那些没空写的小需求,龙虾真能做吗?_AI&大模型_InfoQ 中文站_InfoQ精选视频 从 Pandas 到生产:使用任意 IDE 进行可扩展的 ML 数据管道与分布式处理 | BUILD 2025_AI&大模型_王玮_InfoQ精选视频 pnpm 11 候选版本发布,带来 ESM 分发、供应链默认设置以及新的存储格式 银行业PDF表格提取方案重构:基于Java的分层方案 GPT-5.5 赢了 Opus 4.7 和 Mythos?奥特曼晒黄仁勋内部信:英伟达全员用上 Codex! Cloudflare 推出 Think:一款面向 AI 代理的持久化运行时 1850亿美元天价支出、75%代码由AI生成!谷歌正式宣告:全面转向智能体工作流 xAI落后太多,马斯克“开大”重金求购Cursor,100亿美金“分手费”都敢签! Pulumi 新增对 Bun 运行时的全面支持 姚顺雨腾讯模型首秀!不卷参数只做 “听话打工人”,Hy3 preview登场 | 附实测 老板让你“忽悠”投资人,你敢发给龙虾吗?_AI&大模型_InfoQ 中文站_InfoQ精选视频 Gemini CLI 引入子代理机制,实现任务委派与并行代理工作流 清华系团队星工聚将完成数千万天使轮融资,轮式机器人拿下头部制造企业亿级大单 Pretext.js 绕过 DOM 布局重排,实现 120 FPS 的高级交互体验 靠“AI 云”爆红的 Vercel,栽在一个第三方AI工具手里!IPO前夕遭黑,200万美元赎金谈崩? 高能研讨会|端侧 AI 正在重写实时感知效率上限_AI&大模型_王玮_InfoQ精选视频 2050大会看这篇就够了|报名、交通食宿指引大全 Java 近期资讯:OpenJDK JEP、Jakarta EE 12、Spring Framework、Micrometer、Camel、JBang 金融智能的架构编排:基于 Snowflake Cortex Agents 实现结构化与非结构化数据统一分析 | 技术实践 在AK大神爆火的任务里,摸清国产AI真实水平 百灵Ling-2.6-flash 正式发布:高 Token 效率,以 1/10 消耗实现 SOTA 级 Agent 能力 当 PM 懂AI,当技术懂产品:AI 时代产品力的双向进化|PM x AI产品力领航者大会即将开幕 为 AI 智能体设计记忆机制:揭秘 LinkedIn 的认知记忆智能体 获奖名单公布|2026主题征文第一期|分享你最有价值的龙虾场景与核心 Skill_热门活动_InfoQ写作社区官方_InfoQ写作社区
构建生产就绪的 tRPC API:Apollo Federation 的 TypeScript 替代方案
作者:Dinesh Ku · 2026-04-27 · via InfoQ - 促进软件开发领域知识与创新的传播

我得跟你们说句实话。六个月前,我还是 GraphQL Federation 的布道者。我们花了六个月的时间,利用 Apollo 构建了一个联邦图,其中包含模式拼接、网关配置,以及一套复杂的 CI/CD 管道(每次提交都会重新生成类型)。纸上谈兵时,这套方案看起来很完美。但在生产环境中呢?每次部署都像是要发生一场灾难。

转折点发生在周五下午的一次例行部署中。我们的产品团队更新了某项服务中的一个字段类型,模式重新生成成功,测试通过,于是我们将其发布。三十分钟后,我们的移动应用开始崩溃,原因是 iOS 客户端仍在使用两小时前生成的旧类型。模式的版本已经更新,网关也已经升级,但客户端代码生成尚未运行,因为有人忘记触发它了。这正是 GraphQL 联邦架构中的一个典型痛点。

那时,我开始研究 tRPC。最吸引我的是,它不需要繁琐的模式定义就可以实现端到端的类型安全。不需要 SDL 文件,不需要代码生成步骤,也不需要联邦网关。从头到尾,只需 TypeScript 即可。自然,我还是心存疑虑。毕竟我们已经在 Apollo 上投入了大量的资源。但在看到一些大规模部署 tRPC 的公司所提供的生产环境指标后,我说服团队构建了一个概念验证。

下文记录了我们的完整迁移过程,包括我们犯过的错误、意想不到的性能提升,以及对当前生产环境架构的回顾——该架构每日能够处理 240 万次请求,并保持 99.97% 的可用性。这不是一份通过简单项目介绍 tRPC 的教程,而是将 tRPC 投入生产环境应用所需的实际经验。

图 1: tRPC 如何在没有模式定义的情况下实现端到端安全性

技术现实:tRPC 究竟能为你带来什么

没有模式开销的类型安全

关于 GraphQL Federation,有件事没人会告诉你:模式会成为单点故障。使用 tRPC 时,你的 TypeScript 类型就是契约。没有中间表示形式,无需维护 SDL,也不需要在不同的环境间保持模式注册表的同步。

在运行 Apollo Federation 时,典型的类型变更流程如下:更新 GraphQL 模式 → 运行代码生成 → 提交生成的文件 → 更新解析器实现 → 更新客户端查询 → 运行客户端代码生成 → 部署两项服务 → 祈祷一切正常。

使用 tRPC 呢?更新 TypeScript 接口 → 就这样。客户端会立即知道,因为它们共享相同的类型定义。

图 2:在每分钟 10000 次请求的持续负载下测得

真正重要的是性能

我们进行了生产环境负载测试,将旧版的 Apollo Federation 架构与新版的 tRPC 实现方案进行了对比。测试结果令人震惊。对于我们的无服务器函数而言至关重要的冷启动性能提升了 75% 。Apollo Federation 的网关开销在冷启动时会增加 180 毫秒,而 tRPC 仅需 45 毫秒。这还是在我们尚未进入实际业务逻辑之前。

在持续负载下,其平均响应时间从 38 毫秒降至 12 毫秒。但真正关键的是 P95 和 P99 延迟。使用 Apollo 时,我们的 P95 延迟为 85 毫秒,P99 延迟为 156 毫秒。迁移后,P95 延迟降至 28 毫秒,P99 延迟降至 42 毫秒。这些尾部延迟会严重影响用户体验,尤其是在移动网络上。

关于资源包大小的故事同样令人惊叹。我们基于 Federation 的 Apollo Client 设置在 gzip 压缩后为 142KB 。而采用 tRPC 搭配 React Query 的方案呢?仅需 28KB 。也就是说,大小减少了 80%。在网速较慢的情况下,这意味着页面初始加载速度可以提升 2 到 3 秒。真实用户立刻就会感受到这一差异。

生产架构:我们实际上是如何构建这个系统的

行之有效的单库设置

我们的生产环境是一个基于 pnpm 工作区的单库(monorepo),前端采用 Next.js 14 App Router,所有 API 通信均通过 tRPC 实现。我们有 12 个微服务,每个微服务都暴露自己的 tRPC 路由器,并由一个网关层将它们全部整合在一起。在实际应用中,其结构如下:

图 3:12 个微服务,每日 240 万次请求,99.97% 的可用性

每个服务都有自己的业务逻辑和数据库。用户服务与 PostgreSQL 通信,产品服务使用 MongoDB 存储商品目录数据,订单服务则利用 Redis 进行会话管理。tRPC 的优势在于,类型安全贯穿于整个技术栈。当产品服务更改字段类型时,TypeScript 会立即向所有调用方发出警告。

请求批处理和缓存策略

人们对 tRPC 的一个担忧是,它不像 GraphQL 那样内置请求批处理功能。实际情况是:对于 90% 的用例来说,React Query 的批处理功能已经绰绰有余,而且实际上比 GraphQL 的 DataLoader 模式更容易调试。我们在生产环境中每分钟处理 10000 次请求,批处理功能运行得非常完美。

我们的缓存层结合了用于共享数据的 Redis 以及客户端一侧的 React Query 智能缓存。这种组合非常强大,因为 React Query 能精确掌握已有的数据并能即时从缓存中提供数据,而我们的服务器端 Redis 缓存则能高效地处理跨用户数据。目前,产品数据的缓存命中率为 87% ,用户偏好数据的缓存命中率为 92% 。

迁移过程:我们实际上是如何操作的

阶段 1 :绞杀榕模式

我们没有进行彻底重写。那样做需要六个月的毫无业务价值的工作,这会让管理层陷入恐慌。相反,我们采用了“绞杀榕模式”:让两个系统并行运行,逐个迁移端点,验证稳定后再继续推进。

我们首先从流量大但业务风险低的只读端点入手,例如用户资料查询、产品目录查询等。这些操作为我们提供了有关性能和可靠性的真实生产数据,同时又不会危及关键的写入操作。在完全切换之前,我们将两个 API 版本并行运行了三周,对比了错误率和延迟指标。

阶段 2 :处理关键的写入操作

一旦从读取操作上获得了信心,我们就着手处理写入操作,包括订单创建、支付处理、库存更新。这些操作一旦出错,就会造成实际的损失。这正是 tRPC 的类型安全真正大放异彩之处。使用 GraphQL 时,我们要不断地处理可空字段、可选参数以及模式漂移问题。而使用 tRPC,只要类型编译通过,就消除了这一整类的 API 契约错误。这并非因为 TypeScript 强制执行运行时正确性,而是因为客户端和服务器不会因为过时的代码生成悄然发生差异。

在迁移写入端点的过程中,我们总共发现了两个运行时错误,均是和数据库连接池相关,而非 tRPC 本身。值得注意的是:这是一次迁移,而非从零开始的构建,因此业务逻辑已经经过验证。我们构建的 GraphQL 联邦部署同时包含了 API 层和领域逻辑,这也是事件量比较多的原因。虽说如此,这次迁移过程中近乎零的错误率恰恰说明, tRPC 成功消除了代码生成同步问题。

图 4:请注意迁移完成后的急剧下降

实际实现:真正能投入使用的代码

服务器端路由设置

以下是我们在实际的生产环境中使用的路由配置,虽然去除了业务逻辑,但从中可以看出我们实际的使用模式。该配置负责处理跨微服务的身份验证、请求验证、错误处理以及类型合并:

typescript// apps/api/src/trpc.tsimport { initTRPC, TRPCError } from "@trpc/server";import { Context } from "./context";import superjson from "superjson";const t = initTRPC.context<Context>().create({  transformer: superjson,  errorFormatter({ shape, error }) {    return {      ...shape,      data: {        ...shape.data,        zodError:          error.cause instanceof ZodError ? error.cause.flatten() : null,      },    };  },});export const router = t.router;export const publicProcedure = t.procedure;// 身份验证中间件const isAuthed = t.middleware(async ({ ctx, next }) => {  if (!ctx.session?.user) {    throw new TRPCError({ code: "UNAUTHORIZED" });  }  return next({ ctx: { session: ctx.session, userId: ctx.session.user.id } });});export const protectedProcedure = t.procedure.use(isAuthed);

复制代码

Next.js 14 客户端设置

在可能的情况下,我们的 Next.js 配置会使用新的 App Router 并搭配 React 服务器组件。以下是在我们生产环境中实际运行的客户端配置,其中包括用于自动处理请求批处理的 HTTP 批处理链接:

typescript// apps/web/src/trpc/client.tsimport { createTRPCReact } from "@trpc/react-query";import { httpBatchLink } from "@trpc/client";import type { AppRouter } from "@/server/routers/_app";import superjson from "superjson";export const trpc = createTRPCReact<AppRouter>();export function createTRPCClient() {  return trpc.createClient({    links: [      httpBatchLink({        url: process.env.NEXT_PUBLIC_API_URL + "/api/trpc",        transformer: superjson,        headers: async () => {          const session = await getSession();          return {            authorization: session?.token ? `Bearer ${session.token}` : "",          };        },      }),    ],  });}

复制代码

生产环境中使用的流程结构

以下是我们实际使用的流程结构。该模式涵盖了使用 Zod 进行输入验证、数据库事务、错误处理以及遥测——生产环境中所需的一切:

typescript// apps/api/src/routers/product.tsimport { z } from "zod";import { router, protectedProcedure } from "../trpc";import { prisma } from "../db";import { TRPCError } from "@trpc/server";export const productRouter = router({  getById: protectedProcedure    .input(z.object({ id: z.string().uuid() }))    .query(async ({ input, ctx }) => {      const product = await prisma.product.findUnique({        where: { id: input.id },        include: { variants: true, reviews: true },      });      if (!product) {        throw new TRPCError({          code: "NOT_FOUND",          message: "Product not found",        });      }      return product;    }),  create: protectedProcedure    .input(      z.object({        name: z.string().min(1).max(200),        description: z.string().max(5000),        price: z.number().positive(),        inventory: z.number().int().nonnegative(),      })    )    .mutation(async ({ input, ctx }) => {      // 在生产环境里这里会有 Datadog 跟踪      const product = await prisma.product.create({        data: { ...input, createdBy: ctx.userId },      });      // 失效缓存      await redis.del(`product:${product.id}`);      return product;    }),});

复制代码

得与失

我们犯的错

第一个主要错误:试图复现 GraphQL 的字段级批处理。我们花了两周时间构建了一个自定义批处理系统,后来才意识到, React Query 内置的批处理功能完全够用。我们删除了 800 行代码,性能得到了提升,因为这种更简单的方法开销更小。

第二个错误:在客户端进行了过度的验证。我们曾经在客户端和服务器端都运行 Zod 验证,以为这样能更早地发现错误。但实际情况是,因为客户端和服务器端验证结果不一致,引发了令人困惑的错误状态。现在,我们只在服务器端进行一次验证,仅此而已。客户端则信任 TypeScript 的类型。

第三个错误:没有尽早建立完善的监控机制。tRPC 的运行速度极快,以至于我们直到性能退化变得十分明显时才察觉到。现在,我们在每个过程上都部署了 Datadog APM,用于追踪 P50、P95、P99 延迟以及错误率。这带来的开销微乎其微,而可视化价值却无可估量。

我们的意外收获

最令人意外的收获是开发效率的提升。如今,我们团队发布新功能的速度提高了 40%,因为他们无需在 SDL、代码生成和实现之间来回切换。你只需编写过程,TypeScript 会自动推导类型,一切就完成了。无需召开模式同步会议,无需等待代码生成运行,只需专注于编写代码。

第二个收获是新来的开发者上手速度更快。在使用 GraphQL Federation 时,新来的工程师需要花一周时间来理解模式、网关和代码生成管道,然后才能开始贡献代码。而使用 tRPC 后,他们第二天就能提交代码。只要熟悉 TypeScript 和 Next.js,就能轻松掌握我们的 API。

第三个收获在于测试环节。由于 TypeScript 能保证端到端的类型安全,所以我们直接取消了一整类的集成测试。虽然仍然会对业务逻辑进行全面测试,但我们不再需要测试“客户端是否正确处理了该字段”,因为类型系统已经在编译阶段确保其正确性。

什么时候不要使用 tRPC

我们必须明确一点:tRPC 并非万能良方。如果你正在构建一个供第三方调用的公共 API,那么使用 GraphQL 或 REST 会更合理。你需要模式文档、版本控制以及与语言无关的访问方式。而 tRPC 仅支持 TypeScript。

如果你开发的是基于 Swift 或 Kotlin 的移动应用,那么 tRPC 无法帮到你。它非常适合你可以同时控制客户端和服务器端的 Web 应用,但无法像 protobuf 或 GraphQL 那样解决跨平台的类型安全问题。

说实话,如果你的 GraphQL 配置运行良好,且没有遇到我们曾经经历的那些痛点,就没有必要进行迁移。别处未必更好。我们之所以迁移,是因为 Federation 正在严重消耗我们的开发时间并影响生产环境的稳定性。如果你的情况并非如此,那就继续沿用现有的方案吧。

关键指标数据

以下是我们真实的生产数据,对比了 Apollo Federation 最后一个月与完全迁移至 tRPC 后的第一个月。这些数据来自 Datadog APM,而非合成基准测试:

这些数据来自生产环境。该环境每天处理 12 个微服务产生的 240 万次请求。其中,Bug 数量显著减少——生产环境事件量减少了 89%,这意味着需要处理的突发状况减少了,从而能投入更多的精力进行功能开发。

小结:我们会再做一次吗?

当然会。毫不犹豫。在这次迁移过程中,我们花了六周的时间集中精力进行开发,但通过减少 Bug 修复工作、加快功能开发速度以及提升开发体验,我们已经获得了十倍于投入的回报。我们团队发布新功能的速度提高了 40%,用户获得了更佳的性能体验,而我们也睡得更安稳了——因为我们知道,得益于改进后的类型表示,有一整类运行时问题被彻底消除了。

但现实情况是:tRPC 无法解决组织层面的问题。如果你的团队因为流程不完善或责任归属不清而难以驾驭 GraphQL,那么改用 tRPC 也无法神奇地解决这些问题。tRPC 真正能解决的,是与模式同步、类型生成以及 API 契约漂移相关的一系列问题。

如果你正在运行一个 TypeScript 单存储库项目,而且被 GraphQL Federation 的复杂性所困扰,那么你可以认真地考虑下使用 tRPC。不妨从小处着手,先迁移一个服务,评估效果,然后再逐步扩展。这就是我们的做法,它从根本上改变了我们构建 API 的方式。

我们生产环境的完整代码(包括单存储库结构、路由器配置和测试模式)已经发布在 GitHub上。这是经过实战检验的真实生产代码,每天处理 240 万次请求。你可以将其作为自己迁移工作的起点。

声明:本文为 InfoQ 翻译,未经许可禁止转载。

原文链接:https://www.infoq.com/articles/building-trpc-api-typescript/