Search code examples
c#serializationapache-kafkaavrokafka-producer-api

how to Serialize .Net Class to Avro.Generic.GenericRecord for publishing into kafka topic?


I am trying to find a way/helper to convert.Net Class to Avro.Generic.GenericRecord . Currently, I am manually adding field-name and field-value to Generic record. Is there a serializer/converter which I can use to convert the object to generic record and publish on to a kafka topic.

class Plant
{
 public long Id { get; set; }
 public string Name { get; set; }
 public List<PlantProperties> PlantProperties{ get; set; }
}
class PlantProperties
{
 public long Leaves{ get; set; }
 public string Color{ get; set; }
}

Please suggest.


Solution

  • Assuming you are using the Confluent Schema Regsitry, you can use their .NET client1

    https://github.com/confluentinc/confluent-kafka-dotnet

    Copied from the examples folder

        using (var serdeProvider = new AvroSerdeProvider(avroConfig))
        using (var producer = new Producer<string, GenericRecord>(producerConfig, serdeProvider.GetSerializerGenerator<string>(), serdeProvider.GetSerializerGenerator<GenericRecord>()))
        {
            Console.WriteLine($"{producer.Name} producing on {topicName}. Enter user names, q to exit.");
    
            int i = 0;
            string text;
            while ((text = Console.ReadLine()) != "q")
            {
                var record = new GenericRecord(s);
                record.Add("name", text);
                record.Add("favorite_number", i++);
                record.Add("favorite_color", "blue");
    
                producer
                    .ProduceAsync(topicName, new Message<string, GenericRecord> { Key = text, Value = record })
                    .ContinueWith(task => task.IsFaulted
                        ? $"error producing message: {task.Exception.Message}"
                        : $"produced to: {task.Result.TopicPartitionOffset}");
            }
        }
    
        cts.Cancel();
    }
    

    Where, in your case, update the record.Add uses accordingly


    However, since you have a class, therefore, you should try to use SpecificRecord, rather than serializing back and forth between Avro and a .NET class via a GenericRecord. See the README section on the AvroGen tool for examples of this

    1. I'm not aware of an alternative .NET library