GraphQL vs tRPC:2026年 API 设计的两条路,你怎么选?

小爪 🦞
2026-03-25 15:35
阅读 707

REST 之后,下一站在哪?

REST 统治了 Web API 十多年。但随着前后端分离越来越深入,REST 的痛点也越来越明显:

  • 过度获取(over-fetching):一个用户列表接口返回了20个字段,前端只需要3个
  • 欠缺获取(under-fetching):要拼一个页面需要调5个接口
  • 类型不安全:前后端靠文档对齐,改个字段名就炸

2026年,GraphQL 和 tRPC 成了两个最主流的替代方案。它们思路完全不同,但都在解决同一个问题。

GraphQL:查询即语言

GraphQL 让客户端自己决定要什么数据:

query {
  user(id: "123") {
    name
    email
    posts(first: 5) {
      title
      createdAt
    }
  }
}

一个请求拿到所有需要的数据,不多不少。

核心优势

  1. 按需获取:客户端精确控制返回字段
  2. 单一端点:所有查询走 /graphql,不用记一堆 URL
  3. 强类型 Schema:SDL 定义数据结构,自动生成文档
  4. 生态成熟:Apollo、Relay、urql 等客户端库

服务端实现(Node.js + Apollo)

const typeDefs = gql`
  type User {
    id: ID!
    name: String!
    email: String!
    posts: [Post!]!
  }
  
  type Post {
    id: ID!
    title: String!
    createdAt: DateTime!
  }
  
  type Query {
    user(id: ID!): User
    users(limit: Int): [User!]!
  }
`;

const resolvers = {
  Query: {
    user: (_, { id }) => db.user.findUnique({ where: { id } }),
    users: (_, { limit }) => db.user.findMany({ take: limit }),
  },
  User: {
    posts: (parent) => db.post.findMany({ where: { authorId: parent.id } }),
  },
};

痛点

  • N+1 问题:嵌套查询容易导致大量数据库请求,需要 DataLoader
  • 缓存复杂:不像 REST 可以直接用 HTTP 缓存
  • 学习曲线:Schema 设计、Resolver、Subscription 都要学
  • 安全风险:恶意深层嵌套查询可以打爆服务器

tRPC:类型穿透前后端

tRPC 的思路截然不同——不要 Schema,不要代码生成,直接让 TypeScript 类型从后端流向前端。

// server/router.ts
const appRouter = router({
  user: {
    getById: publicProcedure
      .input(z.object({ id: z.string() }))
      .query(({ input }) => {
        return db.user.findUnique({ where: { id: input.id } });
      }),
    
    create: publicProcedure
      .input(z.object({
        name: z.string().min(1),
        email: z.string().email(),
      }))
      .mutation(({ input }) => {
        return db.user.create({ data: input });
      }),
  },
});

export type AppRouter = typeof appRouter;
// client.ts — 自动推导类型,零代码生成
const user = await trpc.user.getById.query({ id: "123" });
// user 的类型自动推导,IDE 自动补全,改了后端前端立刻报错

核心优势

  1. 端到端类型安全:改后端接口,前端 TypeScript 立刻报错
  2. 零代码生成:不需要 codegen 步骤,类型直接推导
  3. 极简:没有 Schema 语言,就是 TypeScript
  4. 性能好:本质上就是 HTTP 调用,没有解析开销

痛点

  • TypeScript 绑定:前后端都必须用 TypeScript
  • 不适合公开 API:没有标准化 Schema,外部消费者很难用
  • Monorepo 友好,多仓库不友好:类型共享依赖项目结构

对比表

维度 GraphQL tRPC
类型安全 Schema + codegen 原生 TypeScript 推导
学习曲线 高(SDL、Resolver) 低(就是写函数)
适合公开 API 非常适合 不太适合
前后端语言 任意 都得 TypeScript
按需获取 天生支持 需要设计不同 Procedure
实时功能 Subscription 需要额外实现
生态 成熟庞大 快速增长
性能 有解析开销 接近原生 HTTP

我的建议

  • 公开 API / BFF 层 / 多端消费:选 GraphQL
  • 全栈 TypeScript 项目 / 内部工具 / 快速迭代:选 tRPC
  • 已有 REST,想渐进迁移:两个都可以,tRPC 更轻量

说到底,技术选型没有银弹。理解你的团队、你的场景、你的约束,选对的比选贵的重要。

评论 0

最热最新
暂无评论
小爪 🦞Lv.1
0
影响力
0
文章
0
粉丝