← [ BACK_TO_NOTES ]

GraphQL vs REST

从 API 边界、取数粒度、HTTP 语义、缓存、演进、权限与复杂度归属比较 GraphQL 与 REST,避免把两者理解成简单的优劣替代关系。

#synthesis #growing #api #graphql #graphql #rest

[!info] related notes

  • 所属 MOC: graphql-moc
  • 相关概念:
  • 易混淆概念:
  • 相关资源:

GraphQL vs REST

比较范围

GraphQL 和 REST 都可以承载前后端 API,但它们把复杂度放在不同位置。

最重要的问题不是“哪个更先进”,而是:由谁决定返回数据形状,以及系统愿意在哪里承担复杂度。

核心差异

维度RESTGraphQL
API 入口多个资源 endpoint常见单一 GraphQL endpoint
数据形状服务端 DTO 决定客户端在 Schema 范围内选字段
操作语义GET/POST/PATCH/DELETE 等 HTTP 方法Query/Mutation/Subscription
契约URL + method + DTO/OpenAPI强类型 Schema
数据组合常由 endpoint/BFF 聚合Query 天生可组合字段关系
客户端缓存URL/query key 很自然常依赖 entity normalization
性能风险endpoint 粒度设计不合适深查询、N+1、查询复杂度

Over-fetching 与 Under-fetching

REST:

GET /users/u1

如果返回 30 个字段,而页面只需要 name,可能 over-fetch。

如果页面同时需要 user、plan、diagnosis:

GET /users/u1
GET /users/u1/plan
GET /users/u1/diagnosis

可能需要多个 round trip。

GraphQL 允许一次声明:

query {
  user(id: "u1") {
    name
    plan { title }
    diagnosis { summary }
  }
}

但“一个 HTTP 请求”不意味着“一个数据库查询”;resolver 设计不好反而可能制造大量 SQL。

HTTP 语义

REST 天然利用 HTTP:

GET /users/u1
404 Not Found
ETag / Cache-Control

GraphQL 常把不同业务操作装进同一个 HTTP endpoint,因此 transport status 与业务/字段错误不能简单一一对应。

这让 GraphQL API 更统一,但也要求客户端理解 GraphQL 自己的 data + errors 语义。

缓存差异

REST 很容易以请求 URL / query key 为缓存身份。

GraphQL 一个 Query 可以返回多个实体,同一个 User:1 又可能出现在许多查询中,因此 Apollo 一类客户端倾向把结果拆成实体缓存:

User:1
Diagnosis:d9
TrainingPlan:p3

这就是 normalized cache 的来源。

演进方式

REST 常通过:

/v1 → /v2

或保持 DTO 向后兼容。

GraphQL 更倾向:

新增字段
旧字段 @deprecated
逐步迁移客户端

Schema 因而更像一个长期演进的共享合同。

选择规则

优先考虑 GraphQL,当:

  • 页面数据组合复杂;
  • 多客户端需要不同字段组合;
  • 强类型 Schema 与前端 tooling 能产生明显收益;
  • 团队能治理 Resolver、Cache、授权和查询成本。

优先考虑 REST,当:

  • API 资源边界稳定直接;
  • CRUD/命令语义简单;
  • HTTP 缓存、状态码、CDN 等语义很重要;
  • 不需要客户端自由组合数据。

BodySense 的判断

学习 GraphQL 不等于要迁移 BodySense。

当前 REST + TanStack Query + SSE 本身是一套合理组合。GraphQL Lab 的价值是让你理解另一种 API contract/cache/resolver 模型,然后能够回答:换过去究竟解决什么问题,又新增什么成本。

创建于 2026/9/11 更新于 2026/9/16
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本