REST vs RPC:API 设计的两种思维方式
你正在为一个新服务设计 API。应该围绕资源和 HTTP 动词来建模,还是暴露客户端直接调用的过程?这不仅仅是协议选择——这是关于如何思考系统接口的根本性决策。
REST vs RPC API 设计代表了两种截然不同的思维方式,而不仅仅是两种技术。理解每种方法何时表现出色(以及何时结合使用)将使你在未来避免架构上的麻烦。
核心要点
- REST 专注于资源(名词)和标准 HTTP 动词,而 RPC 专注于带参数调用的操作(过程)
- REST 与 HTTP 缓存和现有 Web 基础设施自然契合,而 RPC 在类型安全和流式传输方面表现出色
- 大多数生产系统同时使用两者:REST 用于公共 API,RPC 用于内部服务间通信
- 选择取决于你的约束条件:谁使用 API、缓存需求、流式传输要求,以及操作是基于资源还是基于过程
核心思维差异
REST 以资源为中心思考。你有名词(用户、订单、产品)和一组固定的动词(GET、PUT、DELETE)。URL 标识你要操作的对象,HTTP 方法说明如何操作。
RPC 以操作为中心思考。你有过程(createUser、processPayment、generateReport),通过参数调用它们。重点是你想完成什么,而不是你在操作什么。
两者并无优劣之分。它们各自擅长解决不同的问题。
// REST:面向资源
GET /users/123
PUT /users/123 { "name": "Alice" }
// RPC:面向操作
POST /rpc/getUser { "id": 123 }
POST /rpc/updateUserName { "id": 123, "name": "Alice" }
值得澄清的常见误解
REST 不是”只是 JSON CRUD”。 真正的 REST 包括无状态性、可缓存性和分层系统等约束。大多数”REST API”实际上是带有面向资源 URL 的 HTTP API——这没问题,但这不是一回事。
RPC 并未过时。 像 gRPC 和 Connect 这样的现代实现为 Google、Netflix 和无数初创公司的关键基础设施提供支持。gRPC 运行在 HTTP/2 和 HTTP/3 之上,并在 Kubernetes Gateway API 中获得标准路由支持。
HTTP API vs RPC 不是二选一。 许多生产系统在边缘使用 REST(公共 API、浏览器客户端),内部使用 RPC(服务间通信)。这种混合模式越来越常见。
真正重要的实际权衡
缓存和 HTTP 工具
REST 的资源模型与 HTTP 缓存自然契合。GET /products/123 响应可以被 CDN、浏览器和代理缓存,无需任何特殊配置。
RPC 通常对所有操作使用 POST,HTTP 基础设施默认将其视为不可缓存。你可以让 RPC 可缓存,但这需要明确的设计工作。
类型安全和代码生成
像 gRPC(使用 Protocol Buffers)和 Connect 这样的现代 RPC 框架提供强类型和自动客户端生成。你只需定义一次服务,然后为 TypeScript、Go、Python 等生成客户端。
REST 有 OpenAPI(现在是 3.2 版本,3.1 版引入了完整的 JSON Schema 对齐),提供类似的代码生成。但类型化通常感觉是附加的而非原生的。
Discover how at OpenReplay.com.
流式传输和实时数据
gRPC 原生支持双向流式传输。REST 需要变通方法——Server-Sent Events、WebSockets 或长轮询。
对于浏览器客户端,RPC 通常通过 gRPC-Web、Connect 的 HTTP 友好协议或 JSON 转码工作。这些增加了复杂性,但实现了纯 REST 无法匹配的流式模式。
错误处理
REST API 越来越多地采用 RFC 9457(Problem Details)来标准化错误响应。RPC 框架有自己的错误模型——例如 gRPC 的状态码。
两者都可行。关键是系统内的一致性。
何时选择什么
倾向于选择 REST 当:
- 构建供未知客户端使用的公共 API
- 缓存对性能至关重要
- 你希望与现有 HTTP 工具最大程度兼容
- 你的操作能清晰地映射到资源的 CRUD
倾向于选择 RPC 当:
- 构建内部服务间 API
- 你需要流式传输或双向通信
- 强类型和代码生成是优先事项
- 你的操作本质上是过程性的(“重启服务器”、“运行分析”)
同时使用两者当:
- 你有面向公众的 API(REST)和内部微服务(RPC)
- 系统的不同部分有不同的需求
混合现实
大多数现代 API 架构模式不会只选择一种方法。典型的设置可能通过 API 网关为外部消费者暴露 REST API,同时在内部服务之间使用 gRPC 以获得性能和类型安全。
这不是妥协——这是在每个上下文中使用正确的工具。
结论
从你的约束条件开始。谁使用这个 API?它需要支持什么操作?缓存有多重要?你需要流式传输吗?
REST vs RPC 不是关于哪个”更好”。而是关于哪种思维方式——资源还是过程——更匹配你的问题。通常,答案是两者都需要。
常见问题
可以,许多生产系统正是这样做的。一种常见模式是通过 API 网关为外部消费者暴露 REST API,同时使用 gRPC 进行内部服务间通信。这种方法在各自最重要的地方充分利用了 REST 与 Web 基础设施的兼容性以及 RPC 的性能和类型安全。
由于 Protocol Buffers 的二进制序列化和 HTTP/2 的多路复用,gRPC 通常提供更好的性能。然而,对于许多应用程序来说,差异可能微不足道。使用 JSON 的 REST 通常足够快,其缓存优势可以超过原始速度差异。应根据实际性能要求而非理论基准来选择。
两种方法都支持标准身份验证方法。REST 通常使用 HTTP 头,如带有 Bearer 令牌或 API 密钥的 Authorization。gRPC 也使用元数据头传递令牌。身份验证逻辑保持相似,但 gRPC 的拦截器提供了一种清晰的方式来处理所有过程的身份验证,而 REST 通常在 HTTP 层使用中间件。
你有几个选择。创建面向操作的端点,如 POST /orders/123/cancel,使用自定义 HTTP 方法,或者接受某些操作更适合建模为 RPC 调用。许多 API 对大多数操作使用 REST,但为复杂过程添加 RPC 风格的端点。纯粹性不如对消费者的清晰性和可用性重要。
Truly understand users experience
See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..