如何组合websockets和http来创建一个REST API,使数据保持最新?

Dav*_*erg 46 rest jax-rs websocket restful-architecture

我正在考虑使用websockets和http构建REST API,我使用websockets告诉客户端新数据可用或直接向客户端提供新数据.

以下是它如何工作的一些不同的想法:
ws = websocket

想法A:

  1. 大卫得到所有用户 GET /users
  2. 雅各布添加一个用户 POST /users
  3. 将ws消息发送给具有新用户存在信息的所有客户端
  4. 大卫通过ws和电话回复了一条消息 GET /users

想法B:

  1. 大卫得到所有用户 GET /users
  2. 大卫注册以在完成更改时获取ws更新 /users
  3. 雅各布添加一个用户 POST /users
  4. 新用户由ws发送给David

想法C:

  1. 大卫得到所有用户 GET /users
  2. 大卫注册以在完成更改时获取ws更新 /users
  3. Jacob添加一个用户,POST /users它获得id 4
  4. David通过ws收到新用户的id 4
  5. 大卫得到了新用户 GET /users/4

我死了:

  1. 大卫得到所有用户 GET /users
  2. 大卫注册以在完成更改时获取ws更新/users.
  3. 雅各布添加一个用户 POST /users
  4. 大卫收到一条消息,表示已完成更改 /users
  5. 大卫只通过电话获得三角洲 GET /users?lastcall='time of step one'

哪种选择最好,有哪些优缺点?
这是另一个更好的'Idea E'吗?
我们甚至需要使用REST还是需要所有数据?

编辑
为了解决数据不同步的问题,我们可以提供标题
"If-Unmodified-Since"
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Unmodified-Since
或"E-Tag"
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag
或两者都有PUT请求.

vto*_*ola 9

创意B对我来说是最好的,因为客户专门订阅了资源的变化,并从那一刻开始获得增量更新.

我们甚至需要使用REST还是需要所有数据?

请检查:WebSocket/REST:客户端连接?


Mys*_*yst 6

我不懂Java,但我在这些设计上使用Ruby和C ...

有趣的是,我认为最简单的解决方案是使用JSON,其中REST API只是将method数据(即method: "POST")添加到JSON,并将请求转发给Websocket使用的相同处理程序.

底层API的响应(来自API处理JSON请求的响应)可以转换为您需要的任何格式,例如HTML呈现......虽然我会考虑简单地为大多数用例返回JSON.

这有助于封装代码并在使用REST和Websockets访问同一API时保持DRY.

正如您可能推断的那样,这种设计使测试更容易,因为处理JSON的底层API可以在本地进行测试,而无需模拟服务器.

祝好运!

PS(Pub/Sub)

对于Pub/Sub,我发现最好有一个"钩子"用于任何更新API调用(回调)和一个处理这些事情的单独的Pub/Sub模块.

我还发现将整个数据写入Pub/Sub服务(选项B)而不仅仅是参考号(选项C)或"可用更新"消息(选项A和D)更加资源友好.

总的来说,我还认为发送整个用户列表对大型系统无效.除非你有10-15个用户,否则数据库调用可能会破灭.考虑亚马逊管理员要求所有用户的列表... Brrr ....

相反,我会考虑将其划分为页面,例如每页10-50个用户.这些表可以使用多个请求(Websocket/REST,无关紧要)填充,并使用实时发布/订阅消息轻松更新,或者在连接丢失和重新建立时重新加载.

编辑(REST与Websockets)

至于REST与Websockets ......我发现需求问题主要是"谁是客户?"这一问题的一个子集......

然而,一旦逻辑与传输层分离,比支持两者都非常容易,并且通常支持两者更有意义.

我应该注意,Websockets通常在身份验证方面略有优势(每个连接交换一次凭据,而不是每个请求交换一次).我不知道这是否是一个问题.

出于同样的原因(以及其他原因),Websockets通常在性能方面具有优势...... REST的优势远大于REST传输层(HTTP/1.1,HTTP/2等).

通常,当提供公共API访问点时,这些事情可以忽略不计,我相信实现这两者可能是现在的方法.


Gle*_*rce 5

总结您的想法:

答:当用户在服务器上编辑数据时,向所有客户端发送消息。然后,所有用户都请求更新所有数据。
-该系统可能代表不使用数据的客户端进行许多不必要的服务器调用。我不建议产生所有这些额外的流量,因为处理和发送这些更新可能会变得昂贵。

B:用户从服务器提取数据后,他们随后从服务器订阅更新,该更新向他们发送有关已更改内容的信息。
-这样可以节省大量服务器流量,但是如果不同步,则会向用户发布错误的数据。

C:向订阅数据更新的用户发送有关哪些数据已更新的信息,然后自己重​​新获取。
-这是A和B的最坏情况,因为您将在用户和服务器之间进行额外的往返,只是为了通知他们他们需要请求可能不同步的信息。

D:进行任何更改时,都会通知订阅更新的用户,然后请求对服务器进行最后一次更改。
-这带来了C的所有问题,但也包括以下可能性:一旦不同步,您可能会向用户发送无用的数据,这可能会使我们所知的客户端应用程序崩溃。

我认为此选项E最好:
每次服务器上的数据更改时,将所有数据的内容发送给已订阅它的客户端。这限制了用户和服务器之间的流量,同时使他们获得不同步数据的机会最小。如果连接断开,他们可能会获得过时的数据,但是至少Delete entry 4当您不确定他们是否收到消息说条目5刚刚移入插槽4的消息时,您至少不会向他们发送消息。

一些注意事项:

  • 数据多久更新一次?
  • 每次发生更新时,需要更新多少个用户?
  • 您的传输费用是多少?如果您的用户在移动设备上的连接速度很慢,这将影响您向他们发送邮件的频率和数量。
  • 在给定的更新中更新了多少数据?
  • 如果用户看到过时的数据会怎样?
  • 如果用户使数据不同步怎么办?

最坏的情况是这样的:许多用户,连接速度慢,经常更新大量本不应该过时的数据,并且如果数据不同步,则会引起误解。