数据获取的对比

REST 的痛点

// 获取用户信息
const user = await fetch('/api/users/123');

// 获取用户的订单
const orders = await fetch('/api/users/123/orders');

// 获取订单中的商品详情
for (const order of orders) {
  const products = await fetch(`/api/orders/${order.id}/products`);
}

N+1 查询问题,前端需要多次请求才能组装完整数据。

GraphQL 的解决方案

query {
  user(id: "123") {
    name
    email
    orders {
      id
      total
      products {
        name
        price
      }
    }
  }
}

一次请求,精确获取所需数据。

版本控制的差异

REST 的版本管理

/api/v1/users
/api/v2/users

URL 版本号或 Header 版本号,维护多个版本的代码。

GraphQL 的版本策略

通过字段级别的弃用标记实现平滑演进:

type User {
  name: String
  email: String
  phone: String @deprecated(reason: "Use 'mobile' instead")
  mobile: String
}

无需版本号,客户端按需使用字段。

缓存策略

REST 的缓存优势

基于 URL 的 HTTP 缓存成熟稳定:

GET /api/users/123
Cache-Control: max-age=3600

CDN、浏览器缓存、代理缓存都支持得很好。

GraphQL 的缓存挑战

由于通常是单端点 POST 请求,传统 HTTP 缓存失效。

解决方案:

  • 使用 DataLoader 做请求合并和缓存
  • Apollo Client 的规范化缓存
  • 持久化查询(Persisted Queries)

开发体验对比

REST 的优势

  • 学习曲线平缓
  • 工具生态成熟(Postman、curl)
  • 调试简单直接

GraphQL 的优势

  • 强类型Schema自带文档
  • 代码生成工具(类型定义、请求函数)
  • GraphQL Playground 交互式探索

实际案例分析

适合 REST 的场景

  • 简单的 CRUD 应用
  • 对缓存性能要求极高
  • 团队技术栈较传统

适合 GraphQL 的场景

  • 移动端应用(减少请求次数)
  • 复杂的数据关联关系
  • 前端团队需要灵活查询能力

混合架构的实践

我们的项目采用了混合策略:

  • REST:认证、文件上传、简单查询
  • GraphQL:复杂业务查询、实时订阅

这种折中方案兼顾了两者的优势。

总结

没有绝对的好坏,只有适合的场景:

维度RESTGraphQL
学习成本
数据获取灵活性
缓存支持优秀需额外处理
类型安全需额外工具内置
工具生态成熟快速发展

技术选型要基于团队能力和业务需求,而不是盲目追新。