Avro4s

structible-avro4s is available for Scala 2.12 and 2.13.

It provides derivations for:

  • Encoder
  • Decoder
  • SchemaFor
  • BicoderWithSchemaFor (see below)

These allow you to (de-) serialize value classes as if they were plain values.

Make sure to familiarize yourself with creating structible instances before looking at the examples below.

Dependency

sbt
libraryDependencies += "com.github.cerst" % "structible-avro4s" % "0.6.4"
Maven
<dependency>
  <groupId>com.github.cerst</groupId>
  <artifactId>structible-avro4s</artifactId>
  <version>0.6.4</version>
</dependency>
Gradle
dependencies {
  compile group: 'com.github.cerst', name: 'structible-avro4s', version: '0.6.4'
}

Example (Individual)

You can derive Encoder, Decoder and SchemaFor individually like this:

import com.github.cerst.structible.avro4s.ops._
import com.github.cerst.structible.core.DefaultConstraints._
import com.github.cerst.structible.core._
import com.sksamuel.avro4s.{AvroSchema, Decoder, Encoder, SchemaFor}
import org.apache.avro.Schema

object IndividualExample {

  final class UserId private (val value: Long) extends AnyVal

  object UserId {

    private val structible: Structible[Long, UserId] = Structible.structible(new UserId(_), _.value, c >= 0)

    implicit val decoderForUserId: Decoder[UserId] = structible.toDecoder

    implicit val encoderForUserId: Encoder[UserId] = structible.toEncoder

    implicit val schemaForForUserId: SchemaFor[UserId] = structible.toSchemaFor

    def apply(value: Long): UserId = structible.construct(value)
  }

  final case class User(id: UserId)

  object User {
    val schema: Schema = AvroSchema[User]
  }

}

Example (Compact)

Given that you commonly need all three of them, structible-avro4s provides a custom trait to derive everything in one line:

import com.github.cerst.structible.avro4s.ops._
import com.github.cerst.structible.core._
import com.github.cerst.structible.core.DefaultConstraints._
import com.sksamuel.avro4s.AvroSchema
import org.apache.avro.Schema

object CompactExample {

  final class UserId(val value: Long) extends AnyVal

  object UserId {

    private val structible: Structible[Long, UserId] = Structible.structible(new UserId(_), _.value, c >= 0)

    implicit val bicoderWithSchemaForForUserId: BicoderWithSchemaFor[UserId] = structible.toBicoderWithSchemaFor

    def apply(value: Long): UserId = structible.construct(value)
  }

  final case class User(id: UserId)

  object User {
    val schema: Schema = AvroSchema[User]
  }

}
The source code for this page can be found here.