我了解REST +事件采购的基础知识.我从未使用过严格的RESTful API,也没有参与任何Event Sourcing项目.
有人可以解释两者是否可以一起使用?
在事件源中,客户端发送事件,这是否意味着在服务器上有一个事件集合,API的所有POST都将在该集合上,以向其添加事件?
客户端如何发现它可以发送到服务器的命令?
有时我正在使用CQRS模式和事件采购开发一个小项目.我有一个结构性问题,我不知道要采取哪种解决方案来解决它.
想象一下以下示例:发送一个命令,其中包含银行客户存入一定金额的信息(DepositCommand).在命令处理程序/实体/聚合(对讨论来说不重要)中,必须应用业务规则; 如果客户是前10%中的一个,在账户中有更多的钱赢得一些奖金.
问题是如何获得最新,一致的数据,以了解客户在存款后是否位于前10%.
如果您需要数据库中的数据来应用业务规则,您如何做?如果我不注意最新数据,我会遇到向两个不同客户提供奖品的可能性
期待听到您的意见.
我正在编写我的第一个CQRS应用程序,假设我的系统调度了以下命令:
目前,这些导致相同的事件,仅用过去时(WorgentCreated,TeamCreated等)措辞,但它们包含相同的属性.(我不确定这是否正确,这是我的一个问题)
我的问题在于阅读模型.
我有一个Contingents读取模型,订阅了ContingentCreated,并具有以下方法:
List<ContingentQueries.Contingent> GetContingents();
ContingentQueries.Contingent GetContingent(System.Guid id);
ContingentQueries.Contingent GetContingent(string province);
Run Code Online (Sandbox Code Playgroud)
这些返回的Contingent类看起来像这样:
public class Contingent
{
public Guid Id { get; internal set; }
public string Province { get; internal set; }
}
Run Code Online (Sandbox Code Playgroud)
这适用于列表,但是当我开始考虑单个特遣队及其所有团队的视图的读取模型时,事情开始变得混乱.鉴于这些方法似乎微不足道:
ContingentQueries.Contingent GetContingent(System.Guid id);
ContingentQueries.Contingent GetContingent(string province);
Run Code Online (Sandbox Code Playgroud)
我使用一组团队为这些查询创建了Contingent类:
public class Contingent
{
public Guid Id { get; internal set; }
public string Province { get; internal set; }
public IList<Team> Teams { get; internal set; }
}
public class Team
{ …Run Code Online (Sandbox Code Playgroud) 此问题类似于使用Kafka作为(CQRS)Eventstore.好主意?,但更具体的实施.如何使用kafka作为事件存储,当我有数千个事件"源"(DDD中的聚合根)?正如我在链接问题和其他一些地方读到的那样,我对每个来源的主题都有疑问.如果我按类型将事件拆分为主题,则使用和存储会更容易,但我需要访问特定源的事件流.如何使用kafka进行活动采购?
在研究了大量材料和示例之后,我目前正在开始第一次尝试DDD/CQRS/ES系统.
1)我已经看到了事件源代码示例,其中Aggregates是事件处理程序,并且每个事件的Handle方法是改变对象实例上的状态(它们为将改变状态的事件实现IHandleEvent <EventType>接口)
2)我还看到了一些例子,其中Aggregates看起来就像是对域建模的普通经典实体类.另一个事件处理程序类涉及改变状态.
当然,当从存储库调用重建聚合时,状态由事件处理程序在聚合上进行突变,该存储库调用获取该聚合的所有先前事件,并且当命令处理程序调用聚合上的方法时.虽然在后者中我看过事件在命令处理程序而不是聚合中发布的例子,但我确信这是错误的.
我的问题是方法(1)和(2)之间的利弊是什么
我是CQRS/ES世界的新手,我有一个问题.我正在开发一个使用事件采购和CQRS的发票Web应用程序.
我的问题是 - 根据我的理解,进入系统的新命令(比方说ChangeLineItemPrice)应该通过域模型,以便可以将其验证为合法命令(例如,检查此行项目是否实际存在,价格不违反任何商业规则等).如果一切顺利(命令未被拒绝) - 则会创建并存储相应的事件(例如LineItemPriceChanged)
我没有得到的是在尝试应用命令之前如何将此聚合保留在内存中.如果我在系统中有一百万张发票,每次我想申请一个命令时,我应该播放整个历史记录吗?我是否总是在没有任何验证的情况下保存事件,并在构建视图模型/投影时进行验证?
如果我误解了过程的任何部分,我将非常感谢您的反馈.
谢谢你的帮助!
我正在努力解决Haskell中的一个设计问题,我似乎无法以优雅和令人满意的方式解决这个问题.我有一个系统,其核心是基于事件源的概念:系统的状态是由一系列事件应用到初始状态产生的.有不同类型的事件,每种类型通过类型系列与系统的特定组件相关:
class Model a where
data Event a :: *
apply :: Event a -> a -> a
instance Model Foo where
data Event Foo = Foo Int
...
instance Model Bar where
data Event Bar = Bar String
...
Run Code Online (Sandbox Code Playgroud)
目前系统是100%同步和耦合的,每个模型都可以访问所有其他模型的事件,这很快变得一团糟,所以我想通过引入事件总线 来解耦事情Bus Events,这样我应该能够编写类似于
dispatch :: Bus Events -> Consumer (Event Foo) -> Bus Events将某些消费者附加Event Foo到Bus Events假设中,在Event Foo和之间存在某种形式的子类型或包含Events.然后我可以通过确保消费者每个都在自己的线程中运行来添加异步性.
从系统的角度来看,这将允许我确保每个组件可独立包装,从而将依赖性限制为所有事件的子集.Eventstype将在整个应用程序级别定义.这个问题看起来与离散时间的FRP类似,但我似乎无法绕过它...
有没有人已经处理过类似的事情,如果有的话,怎么样?
编辑:
我提出了以下代码,这些代码没有用,Source但受到@ …
我在服务器和多个客户端之间实现数据同步时遇到问题.我读到了关于事件采购的内容,我想用它来完成同步部分.
我知道这不是一个技术问题,而是一个概念问题.
我只是将所有事件发送到服务器,但客户端设计为不时脱机使用.
该服务器存储每个客户端都应该知道,它不会重播这些事件来服务于数据,因为主要目的是同步的客户端之间的事件,使他们能够在本地重播所有事件的所有事件.
该客户有它一个JSON店,也使所有的事件,并重建从存储/同步事件的所有不同的集合.
由于客户端可以脱机修改数据,因此具有一致的同步周期并不重要.考虑到这一点,服务器应该在合并不同事件时处理冲突,并在发生冲突时询问特定用户.
因此,对我来说主要的问题是确定客户端和服务器之间的差异,以避免将所有事件发送到服务器.我也遇到了同步过程的顺序问题:首先推送更改,首先提取更改?
我目前构建的是服务器端上的默认MongoDB实现,它在所有查询中隔离特定用户组的所有文档(目前仅处理身份验证和服务器端数据库工作).在客户端上,我构建了一个围绕NeDB存储的包装器,使我能够拦截所有查询操作,以创建和管理每个查询的事件,同时保持默认查询行为不变.我还通过实现客户端生成的自定义ID并且是文档数据的一部分来补偿neDB和MongoDB的不同ID系统,因此重新创建数据库不会弄乱ID(同步时,这些ID应该在所有客户中保持一致).
事件格式如下所示:
{
type: 'create/update/remove',
collection: 'CollectionIdentifier',
target: ?ID, //The global custom ID of the document updated
data: {}, //The inserted/updated data
timestamp: '',
creator: //Some way to identify the author of the change
}
Run Code Online (Sandbox Code Playgroud)
为了在客户端上节省一些内存,我将在特定数量的事件中创建快照,以便完全重放所有事件将更有效.
因此,要缩小问题范围:我能够在客户端重放事件,我还能够在客户端和服务器端创建和维护事件,在服务器端合并事件也应该不是问题.使用现有工具复制整个数据库不是一种选择,因为我只是同步数据库的某些部分(甚至不是整个集合,因为文档被分配了它们应该同步的不同组).
但我遇到的麻烦是:
我想问的另一个问题是,将更新直接存储在类似修订版的文档中是否更有效?
如果我的问题不清楚,重复(我发现了一些问题,但他们在我的情况下没有帮助我)或者缺少某些东西,请发表评论,我会尽可能地保持它,以保持简单,就像我一样只写下一切可以帮助你理解这个概念.
提前致谢!
我被要求在事件采购中做一些探索.我的目标是创建一个满足所有传统CRUD操作的微小API层.我现在正在使用一个名为'sourced'的软件包并尝试使用它(使用Nodejs).
但是,我开始意识到,单独使用事件来源并不是很有用.通常,它与CQRS结合.
当我向服务器发送写命令时,我对CQRS的理解是.该应用程序对数据进行了一些验证.并将其保存在事件存储中(我正在使用mongoDB),例如:这是我的事件存储应该是这样的:
{method:"createAccount",name:"user1", account:1}
{method:"deposit",name:"user1",account: 1 , amount:100}
{method:"deposit",name:"user1",account: 1 , amount:100}
{method:"deposit",name:"user1",account: 1 , amount:100}
{method:"withdraw",name:"user1",account1,amount:250}
Run Code Online (Sandbox Code Playgroud)
它包含所有审计信息,而不是最终状态.但是,我很困惑如何处理读取操作.如果我想阅读帐户余额该怎么办?究竟会发生什么?这是我的问题:
如果有任何建议,我将非常感激,如果我的理解错误,请与我联系.
domain-driven-design cqrs event-sourcing event-store microservices
OpenAPI 非常适合 RESTful 服务,目前,我正在通过使用POSTa来破解它以用于异步消息系统(特别是 Kafka) /topic,以便我可以使用 redoc 为 API 创建一个网站。
我想看看是否已经为此建立了记录系统。特别是因为GET /events用于事件源的数据日益庞大。
event-sourcing ×10
cqrs ×6
apache-kafka ×2
api ×1
dddd ×1
event-store ×1
haskell ×1
javascript ×1
mongodb ×1
node.js ×1
openapi ×1
redoc ×1
rest ×1
types ×1