Если вы хотите использовать Avro с такими конструкциями Scala, как классы case, я рекомендую использовать Avro4s .Он имеет встроенную поддержку всех функций Scala и может даже создать схему из вашей модели, если вы этого хотите.
Есть некоторые ошибки с автоматическим выводом классов типов.Это то, что я узнал.
Используйте по крайней мере avro4s версии 2.0.4
Некоторые макросы генерируют код с предупреждениями компилятора, а также устраняют проблемы с удалением бородавок.Нам пришлось добавить следующие аннотации, чтобы заставить наш код компилироваться (иногда ошибка не может быть найдена неявно, но это вызвано ошибкой в сгенерированном макросом коде):
@com.github.ghik.silencer.silent
@SuppressWarnings(Array("org.wartremover.warts.Null", "org.wartremover.warts.AsInstanceOf", "org.wartremover.warts.StringPlusAny"))
Следующая автоматическая деривация класса типов работает только однауровень за один раз.Я создал объект для хранения всех моих экземпляров SchemaFor
, Decoder
и Encoder
для моей схемы.Затем я создал экземпляры классов типов, явно начиная с большинства внутренних типов.Я также использовал implicitly
, чтобы убедиться, что каждый ADT разрешится, прежде чем перейти к следующему.Например:
sealed trait Notification
object Notification {
final case class Outstanding(attempts: Int) extends Notification
final case class Complete(attemts: Int, completedAt: Instant) extends Notification
}
sealed trait Job
final case class EnqueuedJob(id: String, enqueuedAt: Instant) extends Job
final case class RunningJob(id: String, enqueuedAt: Instant, startedAt: Instant) extends Job
final case class FinishedJob(id: String, enqueuedAt: Instant, startedAt: Instant, completedAt: Instant) extends Job
object Schema {
// Explicitly define schema for ADT instances
implicit val schemaForNotificationComplete: SchemaFor[Notification.Complete] = SchemaFor.applyMacro
implicit val schemaForNotificationOutstanding: SchemaFor[Notification.Outstanding] = SchemaFor.applyMacro
// Verify Notification ADT is defined
implicitly[SchemaFor[Notification]]
implicitly[Decoder[Notification]]
implicitly[Encoder[Notification]]
// Explicitly define schema, decoder and encoder for ADT instances
implicit val schemaForEnqueuedJob: SchemaFor[EnqueuedJob] = SchemaFor.applyMacro
implicit val decodeEnqueuedJob: Decoder[EnqueuedJob] = Decoder.applyMacro
implicit val encodeEnqueuedJob: Encoder[EnqueuedJob] = Encoder.applyMacro
implicit val schemaForRunningJob: SchemaFor[RunningJob] = SchemaFor.applyMacro
implicit val decodeRunningJob: Decoder[RunningJob] = Decoder.applyMacro
implicit val encodeRunningJob: Encoder[RunningJob] = Encoder.applyMacro
implicit val schemaForFinishedJob: SchemaFor[FinishedJob] = SchemaFor.applyMacro
implicit val decodeFinishedJob: Decoder[FinishedJob] = Decoder.applyMacro
implicit val encodeFinishedJob: Encoder[FinishedJob] = Encoder.applyMacro
// Verify Notification ADT is defined
implicitly[Encoder[Job]]
implicitly[Decoder[Job]]
implicitly[SchemaFor[Job]]
// And so on until complete nested ADT is defined
}