← 返回博客
技术选型API微服务

REST vs GraphQL vs gRPC:后端 API 协议选型的决策框架(2026)

三种主流 API 协议各有清晰的适用区间:REST 适合面向外部的资源型接口,GraphQL 适合多端聚合与快速迭代的前台,gRPC 适合内部服务间的高性能调用。本文给出一个按"调用方是谁"划分的决策框架,附典型组合架构与三个反模式。

先说结论

选协议的第一问不是”哪个先进”,而是**“调用方是谁”**:

调用方首选理由
外部开发者 / 第三方集成REST + OpenAPI生态兼容性、文档工具链、认知成本最低
自家多端前台(Web/App/小程序)GraphQL(BFF 层)一次请求聚合多资源,前端迭代不等后端
内部服务之间gRPC强契约(protobuf)、低延迟、流式支持

成熟系统不是三选一,而是按接口边界分层混用。下面讲清每个协议的真实优劣与组合方式。

1. REST:默认选项的地位没有动摇

REST 的核心优势不在技术而在生态:OpenAPI 规范撑起了文档(Swagger UI)、Mock、契约测试、SDK 生成、API 网关策略的完整工具链;任何语言任何团队都能立刻上手。

适用区间:资源型 CRUD、对外开放 API、Webhook、需要 HTTP 缓存语义的场景。

真实短板:多资源聚合要么多次往返、要么后端写聚合接口(然后聚合接口越写越多,逐渐失控)——这正是 GraphQL 要解决的问题。

工程底线(无论选不选 REST 都适用):契约先行(OpenAPI 文档先于实现)、版本策略明确(URL 版本或 Header 版本,选一种坚持)、错误结构统一。

2. GraphQL:前台聚合层的利器,不是后端的替代品

GraphQL 的正确位置是 BFF(Backend for Frontend)层:前端按页面需要声明数据形状,一次请求拿全,后端不用为每个页面写聚合接口。多端形态差异大(Web 要全量、App 要精简、小程序要极简)时收益最大。

代价要说清楚:

  • N+1 查询是默认会发生的(resolver 逐条取数),DataLoader 批量合并是必配项而非可选项;
  • 缓存复杂化:HTTP 缓存基本失效(都是 POST /graphql),要靠客户端规范化缓存(Apollo/urql)或持久化查询;
  • 失控查询风险:必须在网关层限制查询深度/复杂度,否则一个深层嵌套查询就是一次小型 DoS。

如果你的前台只有一个 Web 端、页面数据形状稳定——GraphQL 的收益撑不起这些复杂度,REST 就好。

3. gRPC:内部调用的性能与契约之王

protobuf 二进制序列化 + HTTP/2 多路复用,延迟和吞吐都显著优于 JSON over HTTP/1.1;.proto 文件是强类型契约,跨语言代码生成开箱即用;原生支持四种流式模式(一元、服务端流、客户端流、双向流),实时数据管道场景几乎没有对手。

边界也清晰:浏览器不能直连(需 gRPC-Web + 代理)、二进制报文人眼不可读(调试要 grpcurl/反射)、对外开放 API 用它会赶走一半集成方。

它是内部高速公路,不是对外的门面。

4. 典型组合架构

外部开发者 ──REST(OpenAPI)──┐
                            ├─ API 网关 ──┐
Web/App/小程序 ─GraphQL(BFF)─┘             ├─ 服务A ─┐
                                           ├─ 服务B ─┼─ gRPC 互调
                                           └─ 服务C ─┘

网关层做认证、限流、协议转换;BFF 层做聚合与裁剪;服务间走 gRPC。每层职责单一,替换任何一层都不动其他层。

三个反模式

  1. 用 GraphQL 做服务间调用——服务间不需要”灵活的数据形状”(契约本该稳定),却引入了 N+1 和缓存复杂度;这是 gRPC 的主场。
  2. 对外 API 用 gRPC 彰显技术——集成方的痛苦会变成你的售前成本。
  3. REST 接口”GraphQL 化”——GET /users?fields=a,b,c&include=orders.items 这种伪灵活查询,把两边的缺点集齐了:既没有 GraphQL 的类型系统,又丢了 REST 的缓存语义。要灵活就正经上 GraphQL,要简单就守住资源边界。

相关阅读

常见问题

一个项目可以混用 REST、GraphQL 和 gRPC 吗?

可以,而且成熟系统通常就是混合架构:对外开放 API 用 REST(生态兼容性最好),前台 BFF 层用 GraphQL(多端聚合),内部微服务间用 gRPC(性能与强契约)。选型的单位是"接口边界"而不是"整个项目"。

GraphQL 的 N+1 问题怎么解决?

标准解法是 DataLoader 模式:把同一事件循环内的多个单条查询合并成批量查询,配合缓存去重。此外要在网关层加查询深度与复杂度限制,防止恶意或失控的深层嵌套查询把数据库打挂。

gRPC 能直接给浏览器前端用吗?

浏览器不能直接说 gRPC(HTTP/2 帧层控制受限),需要 gRPC-Web 加代理(Envoy 等)转换。所以 gRPC 的主场是服务间调用和移动端/IoT 客户端;纯浏览器前台通常在网关层转成 REST 或 GraphQL。

小团队起步项目直接用 REST 会不会将来后悔?

大概率不会。REST + OpenAPI 是迁移成本最低的起点:文档、测试、网关、监控的生态最全,招人最容易。真正到了多端聚合痛点再引入 GraphQL BFF,到了内部调用性能瓶颈再引入 gRPC——按痛点演进比预先设计更稳。

本文来自 AI Enable Harness 一线交付实践。需要同类系统或优化服务?