REST API 和消息传递

Posted

技术标签:

【中文标题】REST API 和消息传递【英文标题】:REST APIs and messaging 【发布时间】:2018-06-05 06:30:41 【问题描述】:

我有一个系统,它公开了一个带有一组丰富的 CRUD 端点的 REST API 来管理不同的资源。 REST API 也被使用 Ajax 执行调用的前端应用程序使用。

我想让其中一些调用异步并增加可靠性。

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

以前从未使用过消息代理,我想知道它们是否可以“放在”REST API 之前而无需重写它们。

我不想只通过消息系统访问 REST API:对于某些端点,调用必须始终是同步的,可靠性不太重要(主要是因为在发生错误时用户会立即收到反馈)。

对于这个用例来说,完整的 ESB 会是更好的选择吗?

【问题讨论】:

您是否打算通过重新开发前端应用程序将消息放入队列来“隐藏”Rest API?或者有一个使用队列实现的 Rest API 的新实现? 我想对前端应用程序隐藏 REST API。消息传递系统也可以用于服务器到服务器的通信。 API 将可以直接访问,但它的一些端点可以增强以增加可靠性。理想情况下,我还想使用 WebSockets 在浏览器端定义订阅者。 根据您的后端配置,新请求通常在它们自己的线程中处理。因此我猜想从 JS 到你的后端的异步调用不应该是一个真正的问题。不过,您能澄清一下您需要哪些可靠性限制吗?最多一次消费或丢失从前端到后端(或响应)的消息?通常你的前端会填充一个队列,在后端触发一些消费逻辑(类似于通过 HTTP 请求调用的 API),因此我不会将 MQ 放在 API 前面 @RomanVottner 可能我问了太多问题。我最感兴趣的是向现有的 REST API 添加可靠性和异步消息。 API 不仅会被前端调用。我有一些端点需要很长时间才能完成所需的任务。我希望客户立即收到反馈,同时我想确保消息是否已被消息代理发送和接收,它会被传递(迟早)。 您可能正在寻找一种 HTTP 方式(不是 REST;很多人将后者与前者混淆)。立即返回响应的一种简单方法是发送初始 POST 请求,该请求会在新线程中触发服务器上长时间运行的计算。同时,服务器将使用 202 Accepted 确认接收,其中包含带有 URI 的 Link Header,客户端可以调用以轮询状态更新。同时,服务器可以继续其任务,客户端不时要求状态更新。请求完成后返回 200 OK 并返回结果 【参考方案1】:

IMO @EligioEleuterioFontana 你对角色有误解:

一个 RESTful API 消息代理

这是两个不同的子系统,提供不同的服务。

现在,让我们根据您的要求解释他们的角色

您的客户端(桌面浏览器、手机浏览器或应用程序)需要获取/推送数据到您的系统。 (来自 REST API 提及的假设)。 来自客户端的请求使用 HTTP/HTTPS(这是您要求的 REST API 部分)。 任何推送的数据,您都希望使其更具响应性、更快、更可靠。

如果我猜对了,那么我会这样回答:

所有客户端都需要将请求推送到 REST API,因为这不仅仅是简单的 CRUD。 Api 还处理安全(身份验证和授权)、缓存,甚至可能是请求限制等。

REST API 应该始终是客户端的前端,因为这也“隐藏”了 API 使用的子系统。用户不应该看到/知道您的任何子系统选择(例如,您正在使用什么数据库。您是否正在缓存?如果是,使用什么?等等)。

Message Broker 非常适合卸载现在请求的工作并稍后处理工作。有很多方法可以做到这一点(队列或发布/订阅等),但这里的重点是这是客户永远不应该看到或知道的决定。

MB 也非常适合恢复能力(如您所述)。如果某些事情失败了,队列上的消息将在“x”时间之后重新尝试......等等(不,我不会提到毒队列、死信队列等)。

您可以拥有一些同步的 Api 端点。当然!然后让其他人利用一些最终的一致性(即对于那个请求,我会在稍后处理它(即使在 5 秒后),然后将响应返回给客户说“谢谢!明白了!我会做的很快”)。这是您所追求的异步工作流程。

API 端点需要简单、简洁并希望相当稳定。当你改变事情时,你在幕后所做的事情希望能对客户隐藏起来。这包括使用消息代理。


无论如何,我对 REST API 和消息代理的看法以及它们之间的关系如何。

【讨论】:

消息代理和它的大哥服务总线一样是一个集成中间件。它用于集成应用程序或应用程序的组件。 据我所知,最常用的就是集成服务。服务可以是soap服务、rest服务甚至是数据库或文件系统。【参考方案2】:

是否值得研究一下 Google Cloud sub/pub? - https://cloud.google.com/pubsub/docs/overview

【讨论】:

【参考方案3】:

如果我理解您的问题,您希望将 API 端点“注册”为订阅者,以便它可以接收发送到给定队列的消息。

我不认为可以配置消息代理来执行此操作。

例如,如果您想使用消息代理,您的生产者和订阅者都需要使用 JMS API。

我不知道是否可以实现一个订阅者来执行相应的 API 调用。在这种情况下,可靠性会受到影响,因为消息将在 API 调用执行之前出列。如果订阅者在 API 的同一个进程中运行,这是有道理的,但在这种情况下,不清楚为什么应该使用 REST API 而不是库。

【讨论】:

以上是关于REST API 和消息传递的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 云消息传递 REST API Spring

如何将 Azure 通知 REST API 与 Google 云消息传递一起使用

Firebase 云消息传递 - PHP Rest API 不适用于 iOS

微服务是不是可以结合 REST 和消息传递?

Kafka 消息 VS REST 调用

微服务:REST 与消息传递