Monday, February 4, 2019

From REST to CQRS with Clojure, Kafka, and Datomic

Clojure/conj 2015 年的 conference talk --- From REST to CQRS with Clojure, Kafka, and Datomic 是我 2019 年所看到第一篇深受啟發的 talk ,也有 youtube  影片。

首先作者先探討 Restful API  的一些問題:
1.  modeling - jamming every operation into CRUD on some resources is often unnatural, creating impedance mismatch. 
Restful API 可以視為是模仿 Database 的 CRUD 介面 (post, get, patch, put) ,然而,這個 modeling 在本質上,未必適合對各式各樣的問題做建模。
2. mutability semantics
Restful API 隱含了 mutable 語意
3. the kingdom of nouns for distributed system 
最後就是有太多的 API ,然後需要有類似 swagger 之類的 API document 系統 …
4. integration 
integration by API 比 integration by ETL 好一些,但是,還是有許多缺點

然後,作者 (Bobby Calderwood) 提出了一個應用 CQRS + Event sourcing 來設計系統的架構 (Commander Pattern),如下圖:



















新的架構處理了許多舊有的問題:
1. modeling 
web services 的部分只對 communication semantic 做建模,所以只有三種,而非 resources * CRUD 。communication semantic 是指 /command /update /query 三種語意。
2. immutable semantics
/command API 會寫入 command log 。這個 command log 對使用者的 intention 做完整地記錄,相較於儲存進資料庫裡的資料, command log 有更完整的 command story
3. too many APIs
因為新架構的 http endpoint 只有三種: /command /update /query 。
4. integration
新的架構裡可以 integration by events ,因為有儲存下 command log 。要整合的時候,其它系統去訂閱 command log 就可以完整地拿到系統的 states

心得感想:
(*) end-to-end principle
在這個架構裡, Web services 層只用來處理 communication 。 Restful API 的 resources 名稱,其實算是一種 domain semantics,應該要放到 Business Logic 層來實現。這其實很像網路世界的 end to end principle ,因為 Client 與 Business Logic 就像是溝通的兩個端點 ,針對應用 (application) 設計的種種特性 (features),應該要在這兩端來加以實現,而不是在中間的 Web services 層實現。

(*) We shape our tools and thereafter our tools shape us. 
Restful API 的設計,有點像是使用了 SQL/relational database 之後的思維模型會構思的設計。而這個 Commander Pattern 則是使用了 Datomic 之後的思維模型會構思的設計。