2017-10-09 70 views
2

我有一個設計或至少應該根據衆所周知的DDD原則的項目。DDD,活動商店,用戶界面

  1. 後退 - DDD + CQRS +事件存儲

  2. UI - NGRX /存儲

我有很多問題想請教一下,但現在我會堅持這些兩個:

  1. 單個命令/操作執行後應如何更新UI存儲?

一)訂閱response.ok

二)聽取域事件

C)觸發通用事件持創建/更新/刪除對象?

  1. 在每個命令/事件中將整個聚合根dto與其所有實體進行轉換是否是一個好主意,或者最好是有更多的粒度命令/事件只有一個屬性?

回答

6

單個命令/操作執行後應如何更新UI存儲?

從我的聚合的命令方法返回void(尊重CQS);因此,接收命令請求的REST端點僅響應諸如OK, command is accepted之類的內容。然後,它取決於命令是如何在後端服務器內部處理:

  • 如果同步處理命令,然後簡單OK, command is accepted足以作爲用戶界面將自動刷新,新數據將在那裏;
  • 如果命令是異步處理然後事情變得更加複雜,並應返回某種命令ID的,所以像OK, command is accepted and it has the ID 1234-abcd-5678-efgh; please check later at this URI for command completion status

的響應,同時,你可以聽域事件。我使用從後端發送到UI的Server sent events執行此操作;如果UI基於Web,這很有用,因爲可能有多個瀏覽器窗口打開,並且數據將在頁面的後臺進行更新;這很好,客戶很高興。

關於在命令響應中包含來自讀取方的一些數據:這取決於您的具體情況;我避免它,因爲它意味着在寫入時讀取,這意味着我無法在較高層次上將讀取與讀取分開;我喜歡能夠獨立擴展讀取部分的寫入。所以,response.ok是最乾淨的解決方案。此外,它暗示命令/寫入端點會對調用者作出一些查詢假設;爲什麼命令處理程序/命令端點會假設調用者需要哪些數據?但是可能會有例外,例如,如果您希望減少請求的數量,或者如果您使用API​​網關在將命令發送到後端服務器後也執行READ操作。

在每個命令/事件中將整個聚合根dto與其所有實體進行轉換是否是一個好主意,或者最好是有更多的粒度命令/事件:只有一個屬性?

使用CQRS時,我從不發送整個聚集;您有讀取模型,因此每個Aggregate在每個讀取模型上都有不同的表示形式。所以,你應該爲每個UI組件創建一個讀取模型,這樣你就可以保持&只發送顯示在UI上的數據,而不是任何人需要在任何地方顯示的任何神像對象。

+0

非常有用!謝謝!你是否使用任何類型的域事件存儲實現像EventStore? –

+0

@IvelinMatev是的,但我自己的; CQRS庫是https://github.com/xprt64/cqrs-es,MongoDB實現是https://github.com/xprt64/cqrs-eventstore-mongodb(**都只適用於PHP **) –

+0

而且在UI上生成異步處理命令的ID是否是一個好主意? –

1

它是整個聚合根DTO所有 它的實體每個命令/事件傳遞一個好主意,或者最好是能有更多的 細粒度的命令/爲前只有一個單一的事件:財產?

事實上,最好是有粒度命令和事件。 命令和事件應該是不可改變的,表達對象,清楚表達意圖或過去的商業事件。如果對象完全包含即將更改或已更改的數據,則此功能效果最佳。

+0

好的,如果你有一個表單更新單個聚合根對象和根本身的一堆實體 - 你應該爲每個實體發送單獨的命令嗎? –

+0

我不知道你的域名,但提供類似於CRUD的創建(也許是)更新命令/事件可能是有意義的,每個包含更大的部分或聚合根DTO的所有內容。例如。如果您的用戶界面包含一個用戶一次描述聚合根實例的大型創建表單,則在我的操作中,沒有理由將傳輸分割爲多個命令。但這並不意味着每個命令都應該包含整個聚合根。你可能還想出了一些非CRUD操作,它們做非常具體的事情,只應該攜帶一些字段。 – mbnx

3

命令基本上分爲兩類:創建命令和其他命令。

創建命令

隨着創建命令,你常常想回到一個句柄剛剛創建的東西,否則你留在無處暗去進一步操縱它。

  • 我相信這CQS創建命令和CQRS 可以返回某種標識或地點:見my answer here。標識符可能會被命令處理程序知道,它可以在響應中返回它。這很好地映射到REST中的201 Created + Location標頭。

  • 您也可以讓客戶端generate the ID。在這種情況下,請參見下文。

其他所有命令

客戶顯然有對象的地址。它可以簡單地從HTTP部分獲得OK後重新查找它的位置。或者,您可以輪詢該位置,直到指示該命令成功爲止。它可能是一個資源版本ID,Constantin指出的一個狀態,Atom feed等。

另外請注意,Command Handler可能更簡單地返回操作的成功狀態,這是否真的違反了CQS或不(再次,見上面的答案)。