【问题标题】:API - Should aggregation be done in the front-end or back-end app?API - 应该在前端还是后端应用程序中进行聚合?
【发布时间】:2017-06-25 21:39:09
【问题描述】:

我编写了一个从 MongoDB 数据库中检索数据的 API。 我还有一个前端应用程序,它使用来自 API 的数据(如果相关,两个应用程序都是使用 Koa 框架在 Node JS 中编写的)

我需要汇总给定时间段内需要计算的大量数值数据(平均、五分位数等),这可能是按月分组、按年分组或按 personID 分组的所有数据。

我读过一些例子,人们说 API 应该用作数据库层的包装器,只提供对原始数据的访问 - 但对我来说逻辑将存在于数据库上是有道理的(而不是而不是要求前端应用程序搅动数据)。

这是一个常见问题吗?根据您自己的经验 - 让 API 来做聚合还是前端应用程序更好?

示例文档

{
    "date": ISODate("2016-07-31T07:34:05+01:00Z"),
    "value": 5,
    "personID": 123
},
{
    "date": ISODate("2016-08-01T12:53:05+01:00Z"),
    "value": 3,
    "personID": 789
}

【问题讨论】:

  • API 不能是数据库的包装器。它应该包含您的所有用例和业务逻辑。如果您的数据必须聚合才能被使用,请在后端聚合它。可以在客户端计算机上计算快速计算且仅用于在前端视图中显示摘要的聚合。 API 的目标是为您的系统提供一个通用网关;客户端和子系统都必须经历相同的业务案例。这可确保您的系统的一致性和健全性。
  • 感谢 @sturcotte06 - 用户向我的前端应用程序发出请求,然后它向 API 发出请求,这意味着我无法使用客户端计算机进行聚合。出于安全原因,我这样做了(因为我没有为所有用户提供唯一的 API 密钥,并且只有应用程序使用密钥)。只是为了检查我的理解是否正确 - 你是说 API 聚合数据以供前端应用程序使用数据是完全可以接受的吗?再次感谢。
  • 是的,但这不应该是您的 API 的工作。您应该有一个在下班时间运行的聚合过程。它将处理当天的所有数据并将其推送到聚合数据集。然后,您的 API 将此聚合数据集作为资源提供。换句话说,您的 API 负责为业务案例提供服务并应用业务规则。它不应该负责批处理,因为这是一个耗时的过程,并且不能很好地适应快速增长的数据集。但是,处理这些数据是您的后端的责任。
  • 谢谢@sturcotte06 - 这真的很有帮助。我唯一担心的是我的数据全天频繁更新,需要实时查看(除非我的刷新率是每'n'分钟一次)。我在想我可以利用 MongoDB 的聚合函数——当然是应用适当的索引,但我在读完这篇文章后现在正在重新考虑这一点。真的很有帮助,再次感谢您。
  • 这真的取决于你的聚合范围。聚合过程可以每 5 分钟运行一次。唯一的问题是该过程是否需要超过 5 分钟。祝你好运!

标签: node.js mongodb aggregation-framework


【解决方案1】:

您可以从两个角度解决此问题:安全性或性能

从安全角度来看,出于安全目的,您放在前端的任何数据都被视为“脏”。这意味着,如果您接受任何输入,则必须放弃任何输入甚至远程有效的假设。特别是对于大型数据集,您需要对每个创建/更新操作进行某种形式的验证。乍一看,您可能会认为将东西放在客户端会减轻服务器的负担,但除非您希望到处都有漏洞利用,否则您仍然需要对数据进行某种迭代,即使只是为了验证它。

从性能角度来看,将大型数据集移动到客户端会发生任何一种方式,但相同大小的数据不需要返回返回。将操作保留在服务器上意味着您的 Update 样式操作要小得多,因为它们需要通过网络移动整个数据集,但它们可以。更进一步,您可以保证至少您可以控制操作的性能,就像您在客户端上卸载它一样,您将不得不支持每个客户端的机器学位,这是一场噩梦。

tl;dr:安全性和性能在很大程度上决定了服务器端操作,尤其是在大型数据集上。

【讨论】:

  • 感谢您的深思熟虑的回答-我的问题纯粹是针对读取操作的,因为数据已导入其他地方的 MongoDB。为了扩展我的原始问题 - 一个示例查询可能是查看给定年份的月平均值。目前(今年)需要计算大约 30K 文档(数据行),在我看来,通过网络发送这些文档以进行相应的分组和计算似乎很疯狂。也就是说,我的 API 需要被其他人访问,我希望它尽可能“干净”(而不是仅仅为我的前端应用程序量身定制)。
  • 在这种情况下,我推荐一个 REST API,它在齿轮后方执行实际平均值或其他类似的数学运算,并以 JSON 格式(例如)呈现您特定前方的数据- 结束消耗。这允许其他服务也可以使用该服务。确定服务如何呈现数据的标准,并围绕它构建前端。请参阅性能部分的结尾:您的客户做的越少,您直接支持的就越少。
  • 附录:关于您原始帖子中的 cmets,sturcotte06 说您应该确定您的操作是否可以“按需”有效地服务是正确的。其中很多将取决于您的数据是否经常更新。创建记录的频率越高,您需要越频繁地处理整个数据集。
【解决方案2】:

我从来没有想过 API 是关于原始数据的。 API 是应用程序想要的任何东西——很少是 SQL 代理。

构建 web 应用程序的前端工程师可能希望将离散的业务实体逐个组件地插入到他们的前端应用程序中。但他们可能希望能够进行批量调用,并完全掩盖后端性能和复杂性。移动开发人员可能希望上述 AND 获取数据的特殊聚合移动视图。

聚合器最简单的形式是一个简单的网页,它调用多个服务来实现应用程序所需的功能。由于每个服务(服务 A、服务 B 和服务 C)都使用轻量级 REST 机制公开,因此网页可以检索数据并相应地处理/显示它。如果需要某种处理,比如将业务逻辑应用于从各个服务接收的数据,那么您可能有一个 CDI bean 可以转换数据,以便它可以在网页上显示。

http://blog.arungupta.me/microservice-design-patterns/

解释一下 - 您可以通过网页中的小部件访问服务。但如果您需要为前端处理数据,请使用后端服务。

我从“前端视图聚合”中搜索并没有发现任何值得注意的东西。这对我来说意味着,如果您的数据聚合将像单个客户端平台上的几个小部件一样简单 - 尽您所能留在前端。但是一旦应用程序变得复杂,您就会遇到只能通过后端解决方案解决的问题,例如:

  • 跨客户端平台/视图丰富/转换的代码重用
  • 速率限制
  • 性能/缓存
  • 安全性

考虑到上述情况,我认为后端视图聚合是一项重要的技术,很少能大规模使用。

好消息是有一个健康的生态系统,例如Strongloop (js) 或普通的旧 Express (node) 等等。此外,还有大量来自工程英雄的关于如何实现更复杂版本的文献 (spotify, )

编辑:正确的 Kong 目前不支持 Api aggregation

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-13
    • 2018-02-03
    • 2019-02-01
    • 2019-02-20
    • 1970-01-01
    • 2021-10-22
    • 1970-01-01
    相关资源
    最近更新 更多