iT邦幫忙

2023 iThome 鐵人賽

DAY 25
0
Software Development

當rust 遇上 cqrs & es系列 第 25

D25 new version of domain event

  • 分享至 

  • xImage
  •  

先拿book開刀,先改一個新的版本,原需要Book沒有作者欄位,添加上此欄位,並設定為必填項目,在command裡是必填,但aggregate及event為了保持相容性,還是會被迫使用Option選填的方式。

這邊只秀新增的欄位,既有的欄位都不變。

pub struct Book {
    pub author: Option<String>,
}

impl Default for Book {
    fn default() -> Self {
        Self {
            author: None,
        }
    }
}

pub enum BookCommand {
    CreateBook {
        author: String,
    },
}

pub enum BookEvent {
    BookCreated {
        author: Option<String>,
    }
}

更新事件版本,不同版號在未來upcaster裡要個別進行升版實作。

impl DomainEvent for BookEvent {
    fn event_type(&self) -> String {
        "BookEvent".to_string()
    }

    fn event_version(&self) -> String {
        "0.2.0".to_string()             // 這裡把原本的 0.1.0 改為 0.2.0
    }
}

連動一起更新事件及指令的處理:

impl Aggregate for Book {
    async fn handle( /* ... */) {
        match command {
            BookCommand::CreateBook {
                author,
            } => {
                let event = BookEvent::BookCreated {
                    author: Some(author),            // 事件欄位為了相同為Option
                };
            }
        }
    }

    async fn apply( /* ... */) {
        match event {
            BookEvent::BookCreated {
                author,                 // event 已是 Option
            } => {
                self.author = author;   // aggregate 也是 Option
            }
        }
    }
}

#[async_trait]
impl Query<Book> for BookQuery {
    async fn dispatch(&self, aggregate_id: &str, events: &[EventEnvelope<Book>]) {
        for event in events {
            match &event.payload {
                BookEvent::BookCreated {    // Event裡新增欄位配合增加
                    author,
                 } => {
                    let book_dto = BookDto { /* ... */ } // 如有需要這裡的DTO再配合修改
                }
            }
        }
    }
}

上一篇
D24 upcaster
下一篇
D26 impl upcaster
系列文
當rust 遇上 cqrs & es30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言