GraphQL 与 REST 有什么区别?什么时候值得引入?

先理解原理和示例,再练习完整口述与追问。

REST 按资源设计多个端点,响应结构由服务端决定;GraphQL 通常一个端点,基于强类型 Schema,由客户端声明需要的字段,减少过度获取和多次往返。代价是 HTTP 缓存更难、需要处理 N+1 查询、查询复杂度限制和字段级权限。多端需求差异大、需要聚合多个服务时更值得引入。

GraphQL 的 Schema 定义类型、查询(Query)、变更(Mutation)和订阅(Subscription);服务端为每个字段编写 resolver。客户端一次请求就能取到嵌套数据,例如订单及其商品和买家,REST 可能需要多个请求或专门定制接口。Schema 支持自省,可以生成 TypeScript 类型和文档。

问题也随之而来:查询多用 POST 发往同一端点,CDN 和浏览器缓存难以按 URL 命中,常用持久化查询(Persisted Queries)改为 GET;列表中每项都触发一次子查询会造成 N+1,需要 DataLoader 批量合并;恶意的深层嵌套查询会拖垮服务,需要限制深度和复杂度;错误常以 200 状态码加 errors 数组返回,监控要单独处理。

graphql
query OrderDetail($id: ID!) {
  order(id: $id) { id total items { name price } buyer { name } }
}

移动端只取 id total,管理后台取全部字段,两端共用一个 Schema,不必为每端定制接口。

不要说 GraphQL 一定比 REST 快,复杂查询可能更慢;它不是数据库查询语言,数据如何获取完全由 resolver 决定。简单 CRUD 和强依赖 HTTP 缓存的公开资源,REST 往往更合适。

REST 按资源划分多个接口,返回结构由服务端定;GraphQL 用强类型 Schema,客户端声明需要哪些字段,一次请求拿到嵌套数据,减少过度获取和往返,也方便生成类型。代价是缓存不好做、要用 DataLoader 解决 N+1、要限制查询复杂度并做字段级权限。我会在多端需求差异大、需要聚合多个后端服务时考虑它,简单 CRUD 用 REST 更直接。