关于 iii-event-driven-cqrs
iii-event-driven-cqrs 是一项技能,用于在 iii 引擎中实现事件驱动的 CQRS 与事件溯源模式。它介绍命令处理、事件发布、独立读取投影,以及用于查询和命令的 HTTP 端点。
主要功能
- 01分离命令与查询职责
- 02将事件追加到有序状态日志
- 03发布事件并扇出至订阅者
- 04构建独立的查询投影
- 05提供命令和查询 HTTP 端点
适用场景
- 01将库存变更建模为领域事件
- 02根据共享事件维护列表和聚合投影
- 03为现有事件流添加订阅者或投影
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ iii-hq/ skills --skill iii-event-driven-cqrs安装后在 Claude Code 中输入/iii-event-driven-cqrs确认已加载。
详细介绍
事件驱动的 CQRS 与事件溯源
可与以下系统相比较:Kafka、RabbitMQ、CQRS/事件溯源系统
核心概念
在适合任务的情况下使用以下概念。并非所有 CQRS 系统都需要包含这些概念。
- 写入端:命令验证输入,并通过 pubsub 发布领域事件
- 读取端:多个投影分别订阅事件,在状态中构建针对查询优化的视图
- 事件日志:事件以有序日志的形式追加到状态中(事件溯源)
- PubSub 负责扇出——一个事件会传递到所有投影和下游消费者
- HTTP 触发器同时公开命令端点(POST)和查询端点(GET)
架构
HTTP POST /inventory (command)
→ cmd::add-inventory-item → validate → append event to state
→ publish('inventory.item-added')
↓ (fan-out via subscribe triggers)
→ proj::inventory-list (updates queryable list view)
→ proj::inventory-stats (updates aggregate counters)
→ notify::inventory-alert (sends low-stock alerts)
HTTP GET /inventory (query)
→ query::list-inventory → reads from projection state
使用的 iii 原语
| 原语 | 用途 |
|---|---|
registerWorker | 初始化 worker 并连接到 iii |
registerFunction | 定义命令、投影和查询 |
trigger({ function_id: 'state::set/get/list', payload }) | 事件日志和投影状态 |
trigger({ function_id: 'publish', payload }) | 发布领域事件 |
registerTrigger({ type: 'subscribe', config: { topic } }) | 订阅事件的投影 |
registerTrigger({ type: 'http' }) | 命令和查询端点 |
trigger({ ..., action: TriggerAction.Void() }) | 即发即弃通知 |
参考实现
完整可运行示例见 ../references/event-driven-cqrs.js:这是一个库存管理系统,其中的命令会发布领域事件,多个投影会构建针对查询优化的视图。
常见模式
采用此模式的代码通常会根据需要包含以下内容:
registerWorker(url, { workerName })— worker 初始化trigger({ function_id: 'state::set', payload: { scope: 'events', key, value } })— 追加事件日志trigger({ function_id: 'publish', payload: { topic, data } })— 发布领域事件registerTrigger({ type: 'subscribe', function_id, config: { topic } })— 投影订阅- 命令函数使用
cmd::前缀,投影函数使用proj::前缀,查询函数使用query::前缀 - 多个投影分别订阅同一个 topic
const logger = new Logger()— 对每个命令/投影进行结构化日志记录
调整此模式
在适用于任务的情况下使用以下调整方式。
- 在现有事件 topic 上注册订阅触发器,以添加新投影
- 为每个投影使用单独的状态作用域(例如
inventory-list、inventory-stats) - 命令应在发布前进行验证——尽早拒绝无效命令
- 对于关键事件处理,使用
TriggerAction.Enqueue({ queue })替代 pubsub,以确保消息送达 - 事件 ID 应唯一且单调递增,以保证顺序(例如
evt-${Date.now()}-${counter})
模式边界
- 如果任务涉及带有响应式副作用的简单 CRUD,请优先使用
iii-reactive-backend。 - 如果任务需要可重试的持久化多步流水线,请优先使用
iii-workflow-orchestration。 - 当命令/查询分离、事件溯源和独立投影是主要关注点时,继续使用
iii-event-driven-cqrs。
适用场景
- 当任务主要涉及 iii 引擎中的
iii-event-driven-cqrs时,使用此技能。 - 当请求直接要求使用此模式或实现等效方案时触发。
边界
- 切勿将此技能用作无关任务的通用回退方案。
- 如果有更具体的 iii 技能更适合,就不得使用此技能。
- 应用此技能中的示例前,务必先确认环境和安全约束。
评论
支持 Markdown