REST APIs和消息传递

15

我有一个系统,它暴露了一个REST API,具有管理不同资源的丰富的CRUD端点。

这个REST API也被一个前端应用程序使用,通过Ajax执行调用。

我想将其中一些调用变成异步的,并添加可靠性。

显而易见的选择似乎是消息代理(ActiveMQ、RabbitMQ等)。

我以前从未使用过消息代理,我想知道是否可以在不重写API的情况下将其放在API“前面”。

我不想仅通过消息传递系统访问REST API:对于某些端点,呼叫必须总是同步的,而可靠性较低(主要是因为在出错时用户会立即收到反馈)。

对于这种用例,完整的ESB是更好的选择吗?


你的意图是通过重新开发前端应用程序并将消息放入队列来“隐藏”Rest API吗?还是要实现一个新的Rest API实现,其中使用队列进行实现? - sisyphus
我想要隐藏REST API,使其不被前端应用程序所见。消息系统也可以用于服务器之间的通信。API将直接可访问,但其中一些端点可能会增加可靠性。理想情况下,我还想使用WebSockets在浏览器端定义订阅者。 - Eligio Eleuterio Fontana
根据您的后端配置,新请求通常在它们自己的线程中处理。因此,我猜测从JS到您的后端的异步调用不应该是一个真正的问题。但是,您能否澄清您需要什么可靠性约束?例如最多一次消费或从前端到后端(或响应)发出的消息丢失等。通常,您的前端将填充一个队列,触发后端的某些消费逻辑(类似于通过HTTP请求调用的API)。因此,我不会将MQ放在API的前面。 - Roman Vottner
@RomanVottner 可能我问了太多问题。我主要关心的是如何在现有的 REST API 中添加可靠性和异步消息。该 API 不仅会被前端调用。我有一些需要很长时间才能完成所需任务的端点。我希望客户端能立即收到反馈,并且同时,我希望确保如果消息已经被发送并由消息代理接收,它将被传递(早晚)。 - Eligio Eleuterio Fontana
你可能正在寻找一种HTTP方式(而不是REST;很多人将后者与前者混淆)。一种立即返回响应的简单方法是发送一个初始的POST请求,在服务器上触发一个长时间运行的计算,放在新线程中。同时,服务器将通过202 Accepted确认收到,并包含一个Link Header,其中包含客户端可以调用以轮询状态更新的URI。在此期间,服务器可以继续处理其任务,客户端可以不时地请求状态更新。一旦请求完成,将返回一个带有结果的200 OK。 - Roman Vottner
3个回答

6
如果我理解您的问题,您想要将API端点注册为订阅者,以便它可以接收发送到给定队列的消息。
我认为不能配置消息代理来实现此功能。
例如,如果您想使用消息代理,则生产者和订阅者都需要使用JMS API。
我不知道是否可以通过实现订阅者来执行相应的API调用来解决此问题。在这种情况下,可靠性会受到影响,因为在执行API调用之前,消息将被出列。如果订阅者在同一进程中运行API,则可能有意义,但在这种情况下,不清楚为什么应该使用REST API而不是库。

5
我认为@EligioEleuterioFontana先生对以下两种角色的理解存在误解:
- RESTful Api - 消息代理
这两个子系统提供不同的服务。
现在,让我们就它们的角色(与您的要求相关)进行解释:
- 您有一些客户端(桌面浏览器、移动电话浏览器或应用程序),它们需要从您的系统获取/推送数据(从REST API中可以得出这一假设)。 - 客户端的请求使用HTTP/HTTPS(这是您要求中REST API的部分)。 - 任何被推送的数据,您希望使其更加响应迅速、可靠。
如果我理解正确,那么我的回答如下:
- 所有客户端都需要向REST API推送请求,因为它不仅仅是简单的CRUD。API还处理安全性(身份验证和授权)、缓存、可能甚至是请求限制等问题。 - REST API应始终作为客户端的前端,因为它还“隐藏”了API使用的子系统。用户永远不应该看到/知道您的任何子系统选择(例如,您正在使用哪个数据库。您是否在缓存?如果是,使用的是什么等等)。 - 消息代理非常适合卸载当前请求的工作并稍后处理它。这可以通过各种方式完成(例如队列或发布/订阅等),但这里的重点是客户端永远不应该看到或知道这是一个决策。 - 消息代理在弹性方面也非常出色(正如您所指出的)。如果某些事情失败了,队列上的消息将在“x”时间后重新尝试...等等(不,我不会提到毒药队列、死信队列等)。
您可以有一些同步的API端点。当然!然后,还有其他一些端点可以利用某些最终一致性(即,对于该请求,我稍后处理它(即使稍后在5秒钟之后),只需向客户端返回响应,说“谢谢!收到了!我很快就会处理它。”)。这就是您想要的异步工作流。
API端点需要简单、简洁且具有相当稳定性。您在幕后更改事物时所做的事情希望能够隐藏在客户端之外。这包括使用消息代理。
总之,这就是我对REST API和消息代理以及它们彼此之间关系的看法。

1
消息代理就像它的大哥服务总线一样,是一种集成中间件。它用于集成应用程序或应用程序的组件。 - Eligio Eleuterio Fontana
1
据我所知,在最常见的用法中,它集成了服务。服务可以是SOAP服务、REST服务,甚至是数据库或文件系统。 - Eligio Eleuterio Fontana

1

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