ReST通过Websockets是可能的吗?

78

我计划开发一个基于Web的聊天应用程序,它接受ReSTful请求,将其转换为XMPP并将其传递到XMPP服务器。

对于这种基于聊天的应用程序,使用Websockets似乎很有前途,因为可以异步地传递事件(或响应)。但是,如果我将Websockets作为从浏览器传输请求的底层协议,这仍然可以被认为是ReSTful设计吗? 如果是,那么URI,动词(GET,POST ...),参数如何表示在websocket消息中?将它们包装在xml / json中并发送呢?

此外,ReSTful架构规定服务器上不会存储任何会话状态。但是,在这种情况下,当创建XMPP客户端会话时,将在服务器上存储此会话的状态(违反了无状态约束)。

10个回答

78

REST是一种不强制使用协议的架构风格。因此,如果你愿意的话,可以使用Web Sockets、HTTP和FTP实现REST。

使用HTTP的主要原因是它容易且比较简单,可以通过HTTP与任何组件或编程语言进行通信,并且由于HTTP支持具有多个中间代理、防火墙等的分布式环境,因此您可以将服务部署在任何拓扑结构上,任何人都可以访问它。

我的抱怨: 如果你是一个REST迷信者,Roy Fielding的论文是真理的源泉,那么动词从未被认为是语义的一部分。URI才是语义。对于不同操作使用不同的动词已经成为REST在HTTP上优雅的演化,但这并不是“真理”的一部分。你可以查看Roy在他的论文第六章中评估的REST over HTTP的场景。没有提到动词。请注意,这是一个评估场景,而不是规范。

简而言之;

如果您需要通过互联网进行实时双向通信,并且客户端是Web浏览器,则最好选择Web Sockets。然后,您可以在Web Sockets之上实现应用程序级协议来实现RESTful Web Service。


19

可以使用像SwaggerSocket这样的库,在WebSocket上使用REST。


不,Swagger只是基于Websockets的HTTP协议,不算真正的REST。 - gentimouton
6
他所说的只是你可以使用Swagger与REST服务进行接口交互。他从未说过Swagger就是REST……你使用HTTP与REST进行接口交互,这才是重点。 - Slight

8
为什么要在 socket 上构建 REST API?我认为 REST API 的好处是利用标准的 HTTP 协议功能,例如无状态请求、语义化动词(如 GET、DELETE)来构建一个易于理解的API,方便客户端开发人员使用。由于 socket 不提供 HTTP 动词等功能,因此你需要为 socket 构建某种 HTTP 层,这在我看来是不合理的。
如果您真的要构建这样一个东西,我建议以 HTTP 协议为蓝本,并像实现 HTTP 协议一样实现 socket 协议。

12
那么,如何实现与REST的实时通信呢? 使用WebSockets上的REST的概念或多或少是合理的。我想要实现具有实时通信功能的REST语义。但是,我开始觉得这两件事情相当不兼容。 - miguelcobain
5
@miguelcobain 我知道现在已经很晚了,但是REST的整个概念都基于无状态请求。在REST中没有实时通信。 - Davy8
5
所以,你的意思是当有人选择使用REST时,他永远无法实现实时更新吗?我们是否仍然被困在基于间隔的服务器轮询技术中? - miguelcobain
5
通过Websockets实现REST是非常明智的选择。你可以实现一个REST层以保留标准API的所有优势,同时也获得Websockets的好处(较少的数据开销和数据推送)。我很惊讶你得到了这么多赞。 - Spencer
8
@saintedlama这个答案是错误的,正如另一个答案所说,它是一种架构风格,不应该依赖于协议。 - user310291
显示剩余4条评论

4

REST架构风格通常假设有两个实体,即客户端和服务端。

随着我们更多地向实时网络和反应式系统的开发方向迈进,WebSocket会显著地开始取代REST API的使用。

WebSockets允许数据的推送和拉取,这消除了服务器和客户端的概念。

STOMP、AMQP、XMPP可以用作消息传递协议。

数据本身可能是JSON或Google协议缓冲区或Apache Avro。

WebSockets不仅限于Web服务器,还可以在独立应用程序中开发,例如移动应用程序或桌面应用程序。


2
我不明白为什么要将XMPP转换成REST,然后再通过WS运行REST。WebSocket的目的是直接将XMPP协议传输到浏览器中,从而避免所有翻译问题。
有一些JavaScript库可以在浏览器和服务器之间进行XMPP通信。你只需要将来自WS的XMPP流量代理到TCP,然后直接发送到XMPP服务器即可。Kaazing提供了一个网关,可以让你这样做。
如果你想使用开源软件,你需要编写一个JavaScript XMPP库。有一些示例可以展示如何为简单的协议编写JS库。你只需找到一个并将其扩展到XMPP协议即可。
因此,总结一下,整个架构如下:
你的XMPP客户端代码<-> XMPP JavaScript库<-> WebSocket over http<-> WebSocket to TCP代理<-> XMPP服务器
其中,XMPP客户端代码和XMPP JavaScript库在浏览器中运行,WS到TCP代理以及XMPP服务器都在服务器端。

1
客户端没有 XMPP。这个想法是为了消除 Web 开发人员理解/拥有 XMPP 知识的需要。他只需要对 IM 和 Presence 有一个概念。例如:为了创建会话,Web 开发人员在其小部件/应用程序中向某个 URI 发送 POST,带有用户名和密码,而“WS to TCP Proxy” 将转换此请求为 XMPP 消息并将其发送到 XMPP 服务器。 - Krishna Chaitanya P
另一个例子: 要更新在线状态,需要向URI /proxy/presence 发送PUT请求,代理将其转换为XMPP在线状态数据包并发送到XMPP服务器。同样地,对于消息:需要向URI /proxy/message 发送POST请求,代理将其转换为XMPP消息并发送到XMPP服务器,然后由服务器将其传递给接收者。使用REST的原因是,这将使使用API的Web开发人员更容易创建聊天应用程序。 - Krishna Chaitanya P
1
XMPP并不难理解,取决于JavaScript XMPP客户端库的用户友好性,其API实际上比REST更易于使用和更加健壮。人们往往害怕他们不理解的东西,因此即使这样会使事情变得更加复杂和低效,他们也会试图坚持自己所知道的,比如REST。我建议您花几分钟时间了解一下实际使用XMPP有多么容易。没有必要通过将XMPP转换为REST来引入大量的低效率和额外开销。这需要更多的工作,并且会限制您的创造力。 - Axel

1

这位提问者的原始问题是:“是否可以通过Websockets实现ReST?”

这个问题暗示着以下内容:作为传输方式,能否使用Websockets实现REST API。

当然,提问者并不是指以下内容:是否可以在Websockets上实现REST架构风格。他的问题更多地是一个操作性的问题,即是否可以在Websockets通道中交换REST API请求(例如GET、PUT、POST、DELETE等)。

为了回答这个问题,我们必须理解socket和Websockets都是同一类型的接口(全双工、三向握手协议),但不同之处在于socket接口起源于ARPANET参考模型。在该网络模型中,socket是会话层和传输层之间的接口。单词“接口”意味着它驻留在网络层之间,即在它们的边界内。换句话说,socket不是任何特定网络层的一部分。 Websockets也是同一类型的socket接口,但在OSI 7层网络模型中,它们不再驻留在会话层和传输层之间。相反,它们驻留在会话层和表示层之间。为什么要这样做?一个动机是能够利用HTTP协议作为socket的传输方式。HTTP协议有什么特别之处?在企业机构中,有许多网络区域和段,这些安全域受到防火墙的保护。我们知道,防火墙有关联的入站/出站流量规则。如果我们想让两个位于不同网络区域的组件相互通信,我们必须确保相应防火墙上的端口是开放的。这将涉及基础设施、运营团队、业务批准等的协作,并会导致实现一件简单的事情(即两个组件互相通信)需要显著的延迟。 这就引出了我们的用例:Websockets接口放置在会话OSI层(HTTP所在的地方)和表示OSI层(例如TLS所在的地方)之间。默认情况下,所有防火墙上都打开了端口80,因此不需要进行运营和基础架构方面的工作。现在,我们的两个组件可以通过Websockets通信管道交流。

回到提问者的问题。任何类型的字符串列表都可以通过socket传输。Sockets/Websockets是传输各种自定义协议的理想机制,无论是STOMP、HL7、FHIR还是其他协议。GET、PUT、POST、DELETE请求是REST API端点上的不同操作。这些操作采用特定的字符串列表形式,如我们所见,sockets/Websockets非常方便地来回传递字符串列表。然而,在REST over HTTP的情况下,您利用了所有现代浏览器(如Chrome、Firefox、Edge等)以及Web服务器(如Apache、nginx、IIS、OHS、IHS等)中可用的整个HTTP“基础设施”,同时,REST API也依赖于建立在客户端和服务器端中的一种名为HTTP的内置字符串列表协议。这不能应用于Websockets。您必须确保每种类型的客户端和服务器都符合基于Websockets的(自定义)传输解决方案!


所以,如果我们坚持只使用所有支持websocket的现代客户端,我认为我们将能够在websocket上使用REST,对吗? - Harry

1
我知道这篇文章很老,但是想要进一步介入一个观点:“所以,如果我选择REST架构,我就放弃了实时通信的能力?”。

简而言之,不是。我有过一些REST风格的实现经验,它们利用REST来提高兼容性、可发现性,并作为在物联网阴影下跨越不同设备的手段。
然而,除了使用WS外,还有许多抽象可以帮助您实现近乎实时的传输。这些抽象可以让您专注于构建API,并决定消费应用程序的RT组件应如何操作。
如果您想构建REST API并想避免为您的RT需求重新创建轮子,我建议您看看Tibco Smart-Sockets或SignalR等工具。

1
我创建了一个项目,向Web套接字发送函数添加回调:https://github.com/ModernEdgeSoftware/WebSocketR2 消息ID被建立,以便客户端可以实现回调。它处理消息超时后的重试,以及如果连接中断,则重新连接到服务器。然后,您可以通过添加动词和路径来构造您的有效负载,使其尽可能符合RESTful。 这类似于视频游戏工作室使用UDP来实现所需的速度,但他们的网络代码实现了许多TCP的功能以确保可靠性。

0

我刚在提供云解决方案和游戏“服务器端/服务即平台”(SaaS)的某公司博客上发现了一个新话题。

我并不打算宣传这家公司,也没有使用过他们,所以我不知道他们好坏如何。

然而,他们非常清楚地解释了为什么要在REST中使用WebSockets以及其中的好处。可以点击他们的博客阅读一下。


请确保这篇博客的意思在这里得到了表达,因为网站可能会下线。 - Fire
嗯...这里有太多信息需要呈现,我不想复制粘贴并涉及抄袭。有一个官方来源的链接就足够了。 如果那个博客关闭了,我们总是可以使用https://web.archive.org/ ;) - Bryksin

0
REST要求根据无状态约束使用无状态协议,而Websockets是一种有状态的协议,所以不可能实现。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接