diff --git a/Migrating-from-v1.md b/Migrating-from-v1.md new file mode 100644 index 00000000..4ab3316d --- /dev/null +++ b/Migrating-from-v1.md @@ -0,0 +1,117 @@ +Here is the guide of how to migrate from Avro4k v1 to v2 using examples. + +> [!INFO] +> If you are missing a migration need, please [file an issue](https://github.com/avro-kotlin/avro4k/issues/new/choose) or [make a PR](https://github.com/avro-kotlin/avro4k/compare). + +## Pure avro serialization + +```kotlin +// Previously +val bytes = Avro.default.encodeToByteArray(TheDataClass.serializer(), TheDataClass(...)) +Avro.default.decodeFromByteArray(TheDataClass.serializer(), bytes) + +// Now +val bytes = Avro.encodeToByteArray(TheDataClass(...)) +Avro.decodeFromByteArray(bytes) +``` + +## Set a field default value to null + +```kotlin +// Previously +data class TheDataClass( + @AvroDefault(Avro.NULL) + val field: String? +) + +// Now +// ... Nothing, as it is the default behavior! +data class TheDataClass( + val field: String? +) +``` + +## generic data serialization +Convert a kotlin data class to a `GenericRecord` to then be handled by a `GenericDatumWriter` in avro. + +```kotlin +// Previously +val genericRecord: GenericRecord = Avro.default.toRecord(TheDataClass.serializer(), TheDataClass(...)) +Avro.default.fromRecord(TheDataClass.serializer(), genericRecord) + +// Now +val genericData: Any? = Avro.encodeToGenericData(TheDataClass(...)) +Avro.decodeFromGenericData(genericData) +``` + + +## Configure the `Avro` instance + +```kotlin +// Previously +val avro = Avro( + AvroConfiguration( + namingStrategy = FieldNamingStrategy.SnackCase, + implicitNulls = true, + ), + SerializersModule { + contextual(CustomSerializer()) + } +) + +// Now +val avro = Avro { + namingStrategy = FieldNamingStrategy.SnackCase + implicitNulls = true + serializersModule = SerializersModule { + contextual(CustomSerializer()) + } +} +``` + +## Changing the name of a record + +```kotlin +// Previously +@AvroName("TheName") +@AvroNamespace("a.custom.namespace") +data class TheDataClass(...) + +// Now +@SerialName("a.custom.namespace.TheName") +data class TheDataClass(...) +``` + +## Writing an avro object container file with a custom field naming strategy + +```kotlin +// Previously +Files.newOutputStream(Path("/your/file.avro")).use { outputStream -> + Avro(AvroConfiguration(namingStrategy = SnakeCaseNamingStrategy)) + .openOutputStream(TheDataClass.serializer()) { encodeFormat = AvroEncodeFormat.Data(CodecFactory.snappyCodec()) } + .to(outputStream) + .write(TheDataClass(...)) + .write(TheDataClass(...)) + .write(TheDataClass(...)) + .close() +} + + +// Now +val dataSequence = sequenceOf( + TheDataClass(...), + TheDataClass(...), + TheDataClass(...), +) +val avro = Avro { fieldNamingStrategy = FieldNamingStrategy.SnakeCase } +Files.newOutputStream(Path("/your/file.avro")).use { outputStream -> + AvroObjectContainerFile(avro) + .encodeToStream(dataSequence, outputStream) { + codec(CodecFactory.snappyCodec()) + // you can also add your metadata ! + metadata("myProp", 1234L) + metadata("a string metadata", "hello") + } +} +``` + diff --git a/README.md b/README.md index 1b572019..a807bd6e 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ fun main() { - **Avro4k** is highly based on apache avro library, that implies all the schema validation is done by it - All members annotated with `@ExperimentalSerializationApi` are **subject to changes** in future releases without any notice as they are experimental, so please - check the release notes to check the needed migration + check the release notes to check the needed migration. At least, given a version `A.B.C`, only the minor `B` number will be incremented, not the major `A`. - **Avro4k** also supports encoding and decoding generic data, mainly because of confluent schema registry compatibility as their serializers only handle generic data. When avro4k will support their schema registry, the generic encoding will be removed to keep this library as simple as possible. @@ -812,6 +812,9 @@ So to mark a field as optional and facilitate avro contract evolution regarding - Kotlin 1.7.20 up to 1.8.10 cannot properly compile @SerialInfo-Annotations on enums (see https://github.com/Kotlin/kotlinx.serialization/issues/2121). This is fixed with kotlin 1.8.20. So if you are planning to use any of avro4k's annotations on enum types, please make sure that you are using kotlin >= 1.8.20. +# Migrating from v1 to v2 +Heads up to the [migration guide](Migrating-from-v1.md) to update your code from avro4k v1 to v2. + # Contributions Contributions to avro4k are always welcome. Good ways to contribute include: