Fun.CQRS 1.0.0 版本迁移指南:从旧版本平滑升级
2025-06-02 20:37:45作者:秋阔奎Evelyn
前言
Fun.CQRS 是一个基于 Scala 的 CQRS/ES 框架,1.0.0 版本带来了重大的 API 重构。本文将详细介绍如何将现有应用迁移到这个新版本。虽然内部实现没有变化,但用户接口的改动需要开发者进行相应的代码调整。
迁移概览
1.0.0 版本将分三个阶段发布:
- 里程碑1 (1.0.0-M1)
- 里程碑2 (1.0.0-M2)
- 最终版 (1.0.0)
建议开发者按照里程碑顺序逐步迁移,每个阶段完成后进行测试验证。
1.0.0-M1 迁移要点
1. 移除 AggregateLike 特质
旧版本要求聚合体必须继承 AggregateLike 特质:
case class Foo(n: String) extends AggregateLike
新版本移除了这个限制:
case class Foo(n: String)
但聚合体ID仍需实现 AggregateId 特质。
2. 移除 ProtocolLike 特质
旧版本需要定义协议对象:
object FooProtocol extend ProtocolLike {
sealed trait FooCommand extends ProtocolCommand
sealed trait FooEvent extends ProtocolEvent
}
新版本简化了定义:
sealed trait FooCommand
sealed trait FooEvent
这种改变使得:
- 命令和事件不再与框架强耦合
- 可以自由使用 Protobuf/Avro 等工具生成命令和事件类
3. 移除 Metadata 相关特质
旧版本的元数据处理:
case class FooMetadata(...) extends Metadata
sealed trait FooEvent extends MetadataFacet[FooMetadata]
新版本改为:
case class FooMetadata(...)
sealed trait FooEvent {
def metadata: FooMetadata
// 提供便捷访问方法
final def id = metadata.eventId
// 其他方法...
}
4. 引入 Types 特质
新版本通过 Types 特质来组织类型关系:
object Foo extends Types[Foo] {
type Id = FooId // 必须实现 AggregateId
type Command = FooCommand
type Event = FooEvent
}
推荐在聚合体的伴生对象中实现此特质,这样会自动提供隐式实例。
5. 命令和事件处理器重构
事件处理器
从普通函数改为偏函数:
// 旧
handleEvent { evt: FooEvent => ... }
// 新
eventHandler { case evt: FooEvent => ... }
命令处理器
现在需要显式指定返回类型:
import io.funcqrs.behavior.handlers._
commandHandler {
OneEvent { case cmd: FooCommand => FooEvent(...) }
}
支持多种返回类型包装:
OneEvent/ManyEvents- 直接返回事件maybe.OneEvent/maybe.ManyEvents- Option包装attempt.OneEvent/attempt.ManyEvents- Try包装eventually.OneEvent/eventually.ManyEvents- Future包装
6. Behavior DSL 变更
更明确的链式调用:
// 旧
Behavior {
createActions(...)
} {
case foo => foo.someOtherActions
}
// 新
Behavior
.first { createActions(...) }
.andThen {
case foo => foo.someOtherActions
}
7. 后端配置调整
聚合体引用获取方式变化:
// 旧
backend.aggregateRef[Foo](id)
// 新
backend.aggregateRef[Foo].forId(id)
1.0.0-M2 迁移要点
1. 投影API重构
主要变化:
- 事件查询不再与后端强耦合
- 每个投影需要定义自己的事件源
2. 定义 PublisherFactory
new PublisherFactory[Long, RaffleEvent] {
override def from(offset: Option[Long]): Publisher[(Long, RaffleEvent)] = {
// 实现具体的事件发布逻辑
}
}
3. 投影配置
backend.configure {
projection(
projection = new MyProjection(repo),
publisherFactory = myPublisherFactory,
name = "MyProjection"
)
}
4. 偏移量持久化策略
projection(...)
.withCustomOffsetPersistence(
AkkaOffsetPersistenceStrategy.offsetAsLong(actorSys, "ProjectionName")
)
最佳实践建议
- 逐步迁移:按照里程碑顺序分阶段进行
- 类型安全:充分利用新的Types特质
- 明确性:命令处理器返回类型要显式声明
- 测试验证:每个迁移阶段后进行全面测试
- 自定义扩展:考虑实现自己的偏移量持久化策略
结语
Fun.CQRS 1.0.0 通过API重构,降低了框架侵入性,提高了灵活性和明确性。虽然迁移需要一定工作量,但这些改进为长期维护和扩展奠定了更好的基础。建议开发团队预留足够时间进行迁移和测试,确保系统稳定性。
登录后查看全文
热门项目推荐
GLM-5智谱 AI 正式发布 GLM-5,旨在应对复杂系统工程和长时域智能体任务。Jinja00
GLM-5-w4a8GLM-5-w4a8基于混合专家架构,专为复杂系统工程与长周期智能体任务设计。支持单/多节点部署,适配Atlas 800T A3,采用w4a8量化技术,结合vLLM推理优化,高效平衡性能与精度,助力智能应用开发Jinja00
jiuwenclawJiuwenClaw 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。Python0137- QQwen3.5-397B-A17BQwen3.5 实现了重大飞跃,整合了多模态学习、架构效率、强化学习规模以及全球可访问性等方面的突破性进展,旨在为开发者和企业赋予前所未有的能力与效率。Jinja00
AtomGit城市坐标计划AtomGit 城市坐标计划开启!让开源有坐标,让城市有星火。致力于与城市合伙人共同构建并长期运营一个健康、活跃的本地开发者生态。00
CherryUSBCherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(带 USB IP)的高性能 USB 主从协议栈C00
热门内容推荐
最新内容推荐
Degrees of Lewdity中文汉化终极指南:零基础玩家必看的完整教程Unity游戏翻译神器:XUnity Auto Translator 完整使用指南PythonWin7终极指南:在Windows 7上轻松安装Python 3.9+终极macOS键盘定制指南:用Karabiner-Elements提升10倍效率Pandas数据分析实战指南:从零基础到数据处理高手 Qwen3-235B-FP8震撼升级:256K上下文+22B激活参数7步搞定机械键盘PCB设计:从零开始打造你的专属键盘终极WeMod专业版解锁指南:3步免费获取完整高级功能DeepSeek-R1-Distill-Qwen-32B技术揭秘:小模型如何实现大模型性能突破音频修复终极指南:让每一段受损声音重获新生
项目优选
收起
deepin linux kernel
C
27
11
OpenHarmony documentation | OpenHarmony开发者文档
Dockerfile
589
3.99 K
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
364
233
Ascend Extension for PyTorch
Python
423
504
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
911
738
React Native鸿蒙化仓库
JavaScript
320
371
暂无简介
Dart
829
203
🔥LeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer(第 2 版)》、《程序员面试金典(第 6 版)》题解
Java
69
21
🎉 (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统
Vue
1.43 K
803
昇腾LLM分布式训练框架
Python
128
152