GraphQL 与 REST 的取舍
REST 用固定资源接口与 HTTP 缓存语义表达数据,生态成熟、可观测与治理手段现成;GraphQL 由客户端声明所需字段,适合多端聚合与频繁变更的前端需求,代价是服务端复杂度上升:查询解析、复杂度限流、缓存与错误语义都需要自行设计。选择依据是消费方形态与团队治理能力。
基本信息
| REST 优势 | HTTP 缓存成熟、限流按路径简单、调试与观测工具链完整 |
|---|---|
| GraphQL 优势 | 客户端按需取字段、减少多次往返、模式即契约 |
| GraphQL 代价 | 需处理查询复杂度、超深嵌套、批量解析与缓存设计 |
| 常见组合 | 对外开放用 REST,内部前端聚合层用 GraphQL |
维度对照
| 维度 | REST | GraphQL |
|---|---|---|
| 取数方式 | 固定资源表述,可能过取或欠取 | 客户端声明字段,按需返回 |
| 缓存 | HTTP 缓存与网关缓存成熟 | 需应用层缓存与持久化查询 |
| 版本与演进 | 版本化或兼容扩展 | 模式演进,字段逐步废弃 |
| 限流治理 | 按路径与方法限流简单 | 按查询复杂度限流,实现复杂 |
| 错误语义 | 状态码表达结果 | HTTP 200 下用错误数组,需额外约定 |
典型使用场景
- 多端聚合:移动端与网页端需要不同字段组合,避免为每端定制接口
- 减少往返:一次查询取回跨资源的关联数据,降低弱网下的总延迟
- 对外开放:第三方集成用 REST,生态工具与文档更易被接受
- 内部 BFF 层:在前端与服务之间加一层 GraphQL 聚合,屏蔽后端拆分
- 强类型契约:模式文件即接口定义,代码生成减少联调成本
- 渐进引入:先在一个前端模块试点,评估复杂度治理成本后再推广
GraphQL 治理要点
GraphQL 治理要点
# 上线前必须落实的治理项
1) 查询复杂度与深度限制:防止单次查询拖垮后端
2) 持久化查询:只允许白名单查询,降低任意查询带来的风险
3) 批量解析:用 DataLoader 一类批量加载器消除 N+1
4) 授权粒度:字段级校验,避免整对象可见带来的越权
5) 错误约定:区分 HTTP 层失败与业务层错误,统一错误结构
6) 观测:按字段与解析器统计耗时,便于定位慢字段两者可以并存:对外接口保留 REST,给多端前端做一层 GraphQL 聚合,是常见且风险可控的组合方式。
为单一前端引入 GraphQL 往往投入产出不匹配:复杂度治理、缓存与限流都要重建,收益却只在字段裁剪上。