如何为Scala avro4s的通用Trait定义SchemaFor?
为Scala avro4s库的Trait推导多态Avro Schema
针对你要为Event特质推导Schema的需求,avro4s提供了两种常用方式来实现多态类型的Schema生成,以下是具体实现:
方式一:直接生成联合类型Schema
Avro原生支持联合类型,avro4s的SchemaFor.union方法可以直接将子类的SchemaFor实例组合成父特质的SchemaFor:
import com.sksamuel.avro4s.SchemaFor // 定义核心类型 trait Event case class UserCreated(name: String, age: Int) extends Event case class UserDeleted(reason: String) extends Event // 提供子类的SchemaFor实例 given SchemaFor[UserCreated] = SchemaFor[UserCreated] given SchemaFor[UserDeleted] = SchemaFor[UserDeleted] // 为Event推导联合类型的SchemaFor given SchemaFor[Event] = SchemaFor.union[Event, UserCreated, UserDeleted]
这种方式生成的Avro Schema是一个联合类型,包含UserCreated和UserDeleted的Schema,序列化时会自动匹配对应的子类结构。
方式二:带类型标识的Tagged Union
如果需要显式的类型鉴别字段(用于反序列化时明确区分子类),可以使用avro4s的TaggedUnion工具:
import com.sksamuel.avro4s.{SchemaFor, TaggedUnion} // 定义核心类型 trait Event case class UserCreated(name: String, age: Int) extends Event case class UserDeleted(reason: String) extends Event // 为Event生成带类型标识的SchemaFor given SchemaFor[Event] = TaggedUnion.schemaFor[Event]( "UserCreated" -> SchemaFor[UserCreated], "UserDeleted" -> SchemaFor[UserDeleted] )
这种方式生成的Avro Schema是一个记录类型,包含两个字段:
type: 字符串类型,存储子类的标识(比如"UserCreated")value: 联合类型,存储对应子类的实际数据
序列化时会自动添加类型标识,反序列化时通过该标识匹配到对应的子类。
内容的提问来源于stack exchange,提问作者ticofab
相关产品推荐
相关产品推荐

