Nservicebus I';我正在努力理解UI和SOA中其他服务之间的关系

Nservicebus I';我正在努力理解UI和SOA中其他服务之间的关系,nservicebus,soa,Nservicebus,Soa,免责声明:我才刚刚开始从事SOA,所以你必须原谅我的无知 我有一个非常简单的服务,它处理来自第三方API(salesforce)的应用程序。用户界面接受IDs->发送ProcessCmd并启动saga->saga从API导入数据->saga订阅导入的EVT&尝试验证->saga无限期运行检查新信息或手动覆盖->如果saga结束以状态发布ProcessedEvt 现在我的UI是基于Angular/Signal的两个页面 Index.html在提交时(通过JS)填充ID和空字段,并侦听这两个事件。I

免责声明:我才刚刚开始从事SOA,所以你必须原谅我的无知

我有一个非常简单的服务,它处理来自第三方API(salesforce)的应用程序。用户界面接受IDs->发送ProcessCmd并启动saga->saga从API导入数据->saga订阅导入的EVT&尝试验证->saga无限期运行检查新信息或手动覆盖->如果saga结束以状态发布ProcessedEvt

现在我的UI是基于Angular/Signal的两个页面

  • Index.html在提交时(通过JS)填充ID和空字段,并侦听这两个事件。ImportedEvt填充一些字段,ProcessedEvt填充状态字段(接受/拒绝等)。它还激活指向详细信息的链接

  • html只是查询数据库

  • 最初,我在ProcessingSaga中保存了数据,但我在David Boike的文章中读到,这是一种糟糕的做法,因为传奇故事是船长,只下达命令,而没有实际的操舵。所以我在我的服务上添加了另一个ProcessedEvtHandler以保存到DB,但我不知道这是否正确

    有几件事让我困惑:

    • 我记得Udi曾经说过,两个服务不应该因为共享相同的数据而相互依赖。但我也明白,NServiceBus不是为同步查询而设计的。因此,我必须在UI和服务之间逻辑上共享同一个数据库。我可以理解为什么一个UI查询就可以了,但是在我的例子中,为了用户体验,我还想保存到数据库中
    • 因为我将DB逻辑从我的传奇中分离出来,就像我被推荐的那样,我的事件已经失去了它们的自然顺序。很有可能我的UI超过了DB调用,details.html暂时为空。我的两个事件ImportedEvt和ProcessedEvt反映了我的业务模型,这似乎是合乎逻辑的。在我看来,这些都是唯一的事件也是合乎逻辑的。为什么我应该纯粹为了UI而保存一个新事件
    在我看来,尽管我的UI有自己的端点,并且能够像任何其他服务一样发送/接收消息。它实际上不属于同一类。最终的一致性对于幕后的业务规则来说是非常好的,但是会造成糟糕的用户体验,我不明白为什么我不能拥有UI服务共享数据库

    我遗漏了什么吗?

    如果两个物理服务/进程共享一个数据库,那么基本上没有两个逻辑服务,只有一个。这是SOA的基本原则

    听起来您的UI和后端服务在物理上是分开的。即使如此,您可能想问问自己,它们是代表两个逻辑服务还是一个逻辑服务。如果它们代表相同的逻辑服务,那么让它们访问相同的数据库不会违反任何规定

    如果它们代表两个逻辑服务(我怀疑它们是这样做的),考虑不要直接从UI查询数据库;而是通过某种形式的请求/响应(WebAPI、WCF等)查询后端服务,并让它查询数据库。保存到数据库应该通过从UI向后端服务发送命令来完成。命令通常应该是业务动词(例如,“ChangeCustomerAddress”与“UpdateCustomer”)

    为什么我应该纯粹为了UI而保存一个新事件

    我不能完全确定我是否理解问题的这一部分。基本上,您应该在某些事情已经发生时发布事件。如果您正在处理保存到数据库的进程,则通常在数据库提交成功后发布事件。这并不意味着你应该发布像“SavedToDbEvt”这样的事件,但这可能意味着你的ProcessedEvt在数据持久化之前不应该发布

    编辑

    这是一个好问题,您在评论中提出的后续问题也是合理的。不幸的是,我们开始跨越界限进入一些领域,这些领域将使这个问题成为论坛的一个更好的问题,在那里可以进行来回讨论。我会在这里补充一些一般性的想法,但是一个明确的答案可能是不可能的,因为每种情况都是独特的,并且(可能)有不止一种解决方案会起作用

    也许我正在创建比我真正需要的更多的层/服务

    很难说不知道更多。用户界面是要使用其他后端服务,还是只使用您问题中涉及的后端服务?另外,后端逻辑将被其他服务使用,还是仅仅被这个UI使用?如果它们在逻辑上是一个单位,你应该明确考虑通过不在物理上分配它们来简化你的设计。 另一个抽象层(即WCF)有助于缩小差距[…]

    即使您使用的是事件驱动/总线样式的体系结构,也几乎总是需要一些其他服务的请求/响应样式查询。举个简单的例子:如果您的UI服务是全新的,但后端服务已经部署多年了,该怎么办?UI如何获得现有状态,因为它可能错过了后端服务已经发布的多年事件

    虽然您可以通过ESB模拟请求/响应,但这并不是它的目的——我建议在大多数情况下不要使用它

    最后,听起来您确实需要在数据库保存完成后发布一个额外的事件。在我看来,当应用程序成为系统的永久部分时,它代表了一种有趣的状态变化。如果是这样的话,那么这种状态的改变是什么让企业感兴趣的呢?如果你能弄明白这一点,你的活动应该开始变得更有意义,而且很可能会自然地转化为比“SavedToDb”更好的名称