如何合并/合并来自多个RESTful微服务的响应?

Swa*_*rtz 5 rest api-design microservices api-gateway

假设有两个(或多个)RESTful微服务提供JSON。服务(A)存储用户信息(名称,登录名,密码等),服务(B)存储去往/来自该用户的消息(例如sender_id,主题,正文,rcpt_ids)。

服务(A)/profile/{user_id}可能会回应:

{id: 1, name:'Bob'}

{id: 2, name:'Alice'}

{id: 3, name:'Sue'}

等等

响应的服务(B)/user/{user_id}/messages返回发往该{user_id}的消息列表,如下所示:

{id: 1, subj:'Hey', body:'Lorem ipsum', sender_id: 2, rcpt_ids: [1,3]},

{id: 2, subj:'Test', body:'blah blah', sender_id: 3, rcpt_ids: [1]}


使用这些服务的客户端应用程序如何处理将消息列表放在一起以显示名称而不是发件人/ rcpt id的情况?

方法1:提取消息列表,然后开始为sender_id和中列出的每个ID提取配置文件信息rcpt_ids。这可能需要100的请求,可能需要一段时间。相当幼稚和低效,可能无法与复杂的应用程序一起扩展???

方法2:拉出消息列表,提取所有用户ID,并分别对所有相关用户发出批量请求……这假定存在这样的服务端点。在获取消息列表,提取用户ID,发送对批量用户信息的请求以及等待批量用户信息响应之间仍然存在延迟。

理想情况下,我想一次性提供完整的响应集(消息和用户信息)。我的研究将我带到服务层的响应合并...又名方法3:API网关技术。

但是如何实现呢?

我可以获取消息列表,提取用户ID,在后台进行调用并获取用户数据,合并结果集,然后将最终结果提供...在后台进行2种服务都可以正常工作...但是如果消息列表取决于更多服务...如果我需要在后台查询多个服务,进一步解析这些响应,基于次要(三次)结果查询更多服务,然后最终合并...该怎么办?疯狂停止?这如何影响响​​应时间?

现在,我已经有效地创建了另一个“客户端”,该客户端将所有微服务响应组合为一个大型响应……与上面的方法1没什么不同……除了在服务器级别。

在“现实世界”中是这样吗?有什么见解吗?我可以检查基于此类API网关体系结构构建的任何开源项目吗?

nak*_*nak 5

我们用于此类问题的解决方案是对数据和事件进行非规范化以进行更新。

基本上,一个微服务有一个它需要从其他微服务预先获取的数据子集,这样它就不必在运行时调用它们。这些数据通过事件进行管理。其他微服务在更新时,会触发一个带有 id 作为上下文的事件,任何对其感兴趣的微服务都可以使用该事件。这样数据保持同步(当然它需要某种形式的事件故障机制)。这似乎需要做很多工作,但有助于我们做出有关整合来自不同微服务的数据的任何未来决策。我们的微服务将始终拥有本地可用的所有数据,以便在不同步依赖其他服务的情况下处理任何请求

在您的情况下,即显示带有消息的名称,您可以在 Service(B) 中为名称保留一个额外的属性。因此,每当 Service(A) 中的名称更新时,它都会触发一个带有更新名称的 id 的更新事件。然后服务(B) 使用该事件,从服务(A) 获取相关数据并更新其数据库。这样,即使 Service(A) 关闭,Service(B) 也会运行,尽管有一些陈旧的数据,当 Service(A) 出现时,这些数据最终会保持一致,并且您将始终有一些名称显示在 UI 上。

https://enterprisecraftsmanship.com/2017/07/05/how-to-request-information-from-multiple-microservices/


All*_*hua 4

您可能希望在 API 网关上执行响应聚合策略。我写了一篇关于如何在 ASP.net Core 和 Ocelot 上执行此操作的文章,但应该有其他 API 网关技术的对应部分:

https://www.pogsdotnet.com/2018/09/api-gateway-response-aggregation-with.html