原文链接:https://ably.com/topic/websocket-vs-rest

无论您是将客户端连接到服务器、将微服务相互连接,还是将应用程序的一部分连接到外部服务,在通信方法方面,您几乎都会有多种选择。不过,有两个比较突出:WebSocket 和 REST。

好消息是,尽管为应用程序选择核心技术是一项严肃的责任,但由于 WebSocket 和 REST 不同的架构选择、性能特征和实现考虑因素,在 WebSocket 和 REST 之间进行选择相对简单。这意味着双方都可以解决对方可能遇到的问题。

在本文中,我们将阐明 REST 与 WebSocket,涵盖:

  • 回顾一下 REST 和 WebSocket 是什么
  • 他们的技术权衡,包括 WebSocket 与 REST 性能
  • 何时应该使用 REST 以及何时 WebSocket 是更好的选择
  • 如果您使用任一协议,则需要填补一些空白。

但如果您正在寻找快速摘要,那么您需要了解以下内容:

  • 当您需要轻松扩展的基础架构来进行无状态 CRUD 操作并且您希望坚持使用标准 Web 工具时,REST 是理想的选择。例如,如果您正在构建一个 API 来将更新发布到社交网络
  • 当您需要客户端和服务器之间进行实时、双向、低延迟通信时,WebSocket 是正确的选择。例如,如果您正在构建聊天应用程序。

什么是REST?

表述性状态传输 (REST) 是一组原则,定义了通过 HTTP 构建 API 的一种方法。这很容易被忽视,但 REST 不是一种协议,这意味着您可以非常灵活地根据您的需求来塑造它。它的流行很大程度上是由于它的简单性以及它重用了已经用于网络的方法和技术。这在很大程度上定义了它表现良好的用例以及您需要寻找替代方案的用例。

img

让我们快速了解一下 REST 与其他方法的区别。

REST 的主要特征

  • **无状态:**对 REST API 发出的每个请求都是独立且自包含的。这使得扩展变得更加简单。当流量增加时,您可以在负载均衡器后面添加更多服务器,因为特定客户端不需要每次都连接到同一台服务器。尽管 HTTP 和 REST 是无状态的,但您可以通过使用客户端 cookie 来跟踪会话和登录状态来维护长时间运行的会话。
  • **CRUD:**每个 REST 请求都使用标准 HTTP 动词(GET、POST、PUT、PATCH 和 DELETE),与创建、读取、更新、删除操作对齐。
  • 有效负载格式: REST 通常使用 JSON 或 XML 等标准化消息格式进行数据交换。但是您可以使用任何您喜欢的数据格式,只要您设置正确的Content-Type标头即可。
  • **可缓存:**您可以选择允许客户端和中间基础设施缓存响应。这有助于扩展和响应时间。
  • 同步: REST 所依赖的 HTTP 请求-响应周期最适合短暂、简单的事务,其中客户端在继续下一个任务之前等待响应。

什么是 WebSocket?

REST 适用于短暂、无状态的通信,而 WebSocket 则提供持续、低延迟的双向通信通道。这意味着您与 WebSocket 交互的方式是不同的。因此,您无需使用特定端点构建“WebSocket API”,而是打开一个连接,双方可以在需要时交换消息。这使其成为实时应用程序的理想选择,例如聊天、体育或金融数据的实时流媒体,以及 Figma、Miro 和 Google Docs 等交互式实时协作环境。

img

WebSocket 关键特性

  • **持久连接:**每个 REST 请求都需要新的 HTTP 连接,这会由于 HTTP 握手的开销而增加延迟。 WebSocket 打开一次连接,然后根据需要将其保持打开状态,从而减少发送消息所需的时间。
  • 有状态: WebSocket 的持久连接意味着客户端和服务器可以跟踪之前发生的情况,而不必像 REST 那样使用 cookie 来跟踪状态。
  • **全双工通信:**客户端和服务器端都可以在需要时同时发送数据。在 REST 中,只有客户端才能发起新连接。
  • 有效负载格式: WebSocket 适用于离散消息,例如 JSON 对象或 Protobuf 消息。这与发送恒定字节流的流媒体格式形成鲜明对比。重要的是,WebSocket 允许您发送文本或二进制数据,并且由您来处理该数据的序列化和反序列化。
  • 实时: WebSocket 尽可能减少延迟。持久连接和小标头(低至两个字节)都有帮助。

WebSocket 与 REST 概览

正如我们所看到的,WebSocket 和 REST 的设计导致客户端和服务器的连接方式截然不同。让我们回顾一下它们的与众不同之处。

休息WebSocket
沟通模式请求-响应基于事件
状态性无国籍有状态的
可扩展性易于扩展规模更复杂
数据格式二进制或文本二进制或文本
高架更高,因为每次交互都需要新的连接初次握手后降低
用例CRUD API,离散数据单元的无状态传输实时协作、聊天、数据广播、持续数据传输

我应该使用 WebSocket 还是 REST?

在考虑 WebSocket 和 REST 之间的差异时,了解技术能力是很有必要的。但当我们查看用例时,事情变得非常有趣。您应该选择 WebSocket 还是 REST 的问题完全取决于您想要解决的问题。您最终可能会得到两者的混合。

我们以手机银行应用程序为例。其大部分客户端-服务器通信(例如付款)最适合 REST API。收款人详细信息、付款金额和相关数据非常适合请求-响应模型。

但假设您还想将实时客户服务聊天添加到银行应用程序中。仅就该功能而言,WebSocket 将是更好的选择。持久、有状态的连接和低延迟交付使其非常适合交互式实时通信。

所以,也许问题应该是:“我可以同时使用 REST 和 WebSocket 吗?”。答案是坚定的“是”。事实上,根据当前的问题在同一应用程序中使用不同的通信方法是很常见的。

WebSocket 与 REST 用例

为了开始思考应该在哪里使用 REST 以及在哪里应该使用 WebSocket,让我们比较一下它们对一些常见场景的适用性。

使用案例休息WebSocket
聊天效率低下,因为它需要频繁的手动轮询或长轮询等解决方法。具有低延迟的持久双向连接非常适合 WebSocket 聊天。
在线游戏不适合,因为多个请求-响应周期的开销会增加太多的延迟。更好地匹配参与在线游戏的多个玩家的实时更新。
数据更新适用于不频繁更新,其中立即数据刷新并不重要。非常适合更新对时间敏感的仪表板、体育数据和财务数据。
实时协作不切实际,因为延迟太高,而且 REST 缺乏服务器启动消息传输的方法,没有解决方法。双向即时同步意味着所有参与者的更改会同时共享。
服务整合非常适合集成基于无状态交互的第三方服务,例如支付处理。不太适合,因为对持久连接的需求较少
公共API这就是 REST 的优势所在,因为它可以使用标准 Web 工具轻松部署。不太适合,因为没有资源发现机制,而且更难扩展。
物联网设备通信如果设备需要定期发送数据或由状态更改触发,则 REST 可能适合。然而,它限制了单向通信,并且有更好的选择。非常适合需要与物联网网络其余部分进行持续双向通信的设备。

尽管按用例进行思考很有帮助,但您可以应用一条通用规则来决定在何处使用 WebSocket 以及在何处使用 REST。对于实时通信,请使用 WebSocket。对于请求驱动的交互(例如典型的 CRUD 操作),REST 是更好的选择。

REST API 可以使用 WebSocket 吗?

REST 的灵活性意味着您可以精确选择如何实现 REST API。例如,与其他协议相比,HTTP 的延迟可能会让您感到沮丧。你能把它换成 WebSocket 吗?理论上,你可以。 SwaggerSocket开源项目试图做到这一点但 REST 和 HTTP 可以很好地结合在一起,因为它们都是围绕请求-响应模型设计的。 WebSocket 的有状态、基于事件的模型意味着它不是一对一的替代品。如果您想要解决的问题需要 REST,那么就使用 REST。

用于构建 REST 和 WebSocket 基础设施的选项

在 WebSocket 和 REST 之间进行选择实际上只是第一步。请记住,它们都没有告诉您太多有关运行它们所需的基础设施的信息。对于 REST,构建可扩展的 HTTP 后端几乎是一个已解决的问题。但 WebSocket 的情况并非如此。持久的、有状态的连接会增加服务器的负载并使扩展变得复杂。

值得庆幸的是,有各种各样的库、框架和托管服务可用于简化应用程序后端的构建和管理。它们往往分为四类:

  • **托管您自己的后端:**尽管您承担了额外的 DevOps 负担,但您可以使用以下方法之一托管您自己的 WebSocket 后端:
    • **纯 WebSocket 库:**大多数语言都有 WebSocket 协议的官方或半官方实现。例如,“ws”代表 NodeJS。它们为您提供低级 WebSocket 功能,如果您只想要轻量级实现或者确实需要创建自定义解决方案,那么这些功能可能会很好。
    • **功能齐全的消息传递库:**更高一级的是消息传递库,例如用于 .NET 的 SignalR 或用于 NodeJS 的 Socket.IO。他们负责处理更多问题,例如自动重新连接。
    • 使用框架: Spring Boot for Java 本身也支持 WebSocket。
  • **使用专门的托管服务:**根据您的使用案例,可能会有一种软件即服务产品提供专门的 WebSocket 后端。例如,聊天 SaaS API 很常见。但是,您需要熟悉供应商所做的设计选择。
  • 使用后端即服务 (BaaS): Firebase 和 Supabase 等平台提供基于 WebSocket 构建的有限实时功能。然而,通常缺乏可扩展性和消息保证。
  • **使用实时平台即服务 (PaaS):**对于可靠性、数据完整性和可扩展性很重要的应用程序,您应该考虑使用专用的实时 PaaS。 Ably 的实时 PaaS 可帮助您更快地进入市场,为您提供全球托管基础架构,并提供除纯 WebSocket 之外的丰富功能。

借助 Ably,您的应用程序可以利用:

  • **全球边缘网络:**无论您的应用程序的用户位于世界何处,Ablly 边缘位置都可确保整个网络的延迟低于 65 毫秒。在
  • 不仅仅是 WebSocket: Ably 可以根据您的应用程序需求和网络条件选择正确的协议,从 WebSocket、服务器发送事件和 MQTT 等选项中进行选择。
  • 弹性交付: Aly 保证消息按顺序按时到达。
  • 99.999% 的正常运行时间: Ably 的网络可以绕过故障,确保您的应用程序持续交付。
  • **扩展以满足需求:**随着需求的增长,Ablly 的消息数量从数千条扩展到数十亿条。
  • **无论您的技术堆栈如何,都能获得出色的开发人员体验:**凭借适用于超过 25 种语言和框架的 SDK、与常用工具的集成以及行业领先的文档,Ably 为您提供了快速提高生产力的工具。