GraphQL 和 REST 在前端请求层有什么区别?如何选择?
简化版
REST 通常按资源设计多个接口,前端请求固定结构;GraphQL 让前端声明需要哪些字段,服务端按查询返回。GraphQL 能减少 over-fetching 和 under-fetching,适合多端字段差异大、聚合复杂的场景;REST 简单、缓存友好、调试直观,适合大多数常规 CRUD。选择时要看团队复杂度、缓存策略、权限控制、网关能力和后端治理能力。
详细版
两者不是谁淘汰谁,而是适用场景不同。
| 维度 | REST | GraphQL |
|---|---|---|
| 接口形态 | 多个资源 URL | 单入口查询 |
| 数据选择 | 服务端固定返回 | 客户端声明字段 |
| 缓存 | HTTP 缓存天然友好 | 需要客户端和服务端策略 |
| 学习成本 | 低 | 较高 |
| 聚合能力 | 常需 BFF | Schema + resolver |
query {
user(id: "1") {
name
posts { title }
}
}
GraphQL 解决的是数据获取灵活性,不是自动解决性能、安全和缓存问题。
完整版教学
一、REST 的特点
REST 常按资源建模,例如 /users/1、/users/1/orders。它利用 HTTP 方法表达操作,GET 查询,POST 创建,PUT/PATCH 更新,DELETE 删除。
优点是简单、直观、生态成熟,HTTP 缓存和状态码也容易利用。
二、GraphQL 的特点
GraphQL 通过 Schema 描述数据类型,前端写 query 声明需要哪些字段。服务端 resolver 负责取数和组装。
它适合一个页面需要多个资源组合,而不同端需要字段又不一样的场景。
三、over-fetching 和 under-fetching
REST 固定返回结构,可能返回前端不需要的字段,这叫 over-fetching。也可能一个页面需要多次请求才能拿齐数据,这叫 under-fetching。
GraphQL 允许前端精确声明字段,可以缓解这两个问题。
四、缓存差异
REST 的 URL 天然是缓存 key。CDN、浏览器和代理都容易理解 GET 资源。
GraphQL 常用 POST 到同一个 endpoint,HTTP 缓存不如 REST 直接。工程上会配合 persisted query、客户端归一化缓存和服务端缓存。
五、安全和权限
GraphQL 不是只开放一个入口就更安全。它需要处理查询复杂度限制、深度限制、字段权限、N+1 查询和 introspection 暴露。
| 风险 | 说明 |
|---|---|
| 查询过深 | 消耗服务端资源 |
| 字段越权 | 敏感字段被查询 |
| N+1 | resolver 逐条查数据库 |
| 缓存复杂 | 字段级缓存难 |
六、如何选择
如果项目是常规后台 CRUD、接口稳定、团队偏小,REST 更简单。如果多端差异明显、页面聚合复杂、后端能治理 Schema 和 resolver,GraphQL 可以带来收益。
很多公司也会使用 BFF,在 REST 服务之上为前端聚合接口。
七、常见误区与追问
- 误区:GraphQL 一定比 REST 性能好。 如果 resolver 没治理,GraphQL 可能产生 N+1 和复杂查询问题。
- 误区:REST 不能解决字段冗余。 REST 可以通过 BFF、字段参数和视图接口优化。
- 误区:GraphQL 只有一个接口所以更安全。 权限要做到字段级和查询复杂度级,单入口不等于安全。
- 追问:GraphQL 如何缓存? persisted query、客户端归一化缓存、服务端缓存和 CDN 策略配合。
- 追问:什么是 N+1? 查询列表后每个 item 再单独查关联数据,导致请求数据库次数爆炸。
- 追问:前端什么时候更喜欢 GraphQL? 多端字段差异大、页面聚合复杂、接口版本变更频繁时更有吸引力。
八、加强记忆
REST 记成“资源 URL”,GraphQL 记成“前端声明字段”。GraphQL 灵活但治理成本高,REST 简单且缓存友好;选择看复杂度和团队能力。