We have a somewhat similar issue, and maybe you can solve it by using your 'own' serializer/deserializer combo you extend for the avro serializer;
Serialisation could be like this:
- you create a schema with payload (raw bytes probably), a version(you could just set a default), and possibly some other stuff
- in your serialize method you take your date and got to a specificrecordbase, whitch you pass to the avroserilizer to get the bytes.
- in your deserialize method you convert the bytes to the specificracordbase object, and you can read the information with the help of the version.
When you want to update the version you allow you (de)serializer to handle the new version. But this will require updating both the consumer and the producer before you can use the new type of massage. Another approach is to encode the length of the added bytes using a custom serializer, and do the avro serialisation afterwards. We use this so the consumers always now which part of the message contains the avro bytes (along with a minor and major version), and which part of the message is created for the avro deserializer. This way even if we change the size of the bytes we add to the message, 'old' consumer can still read the data. In case we want to use some kind of encryption which we currently do not support the old consumers will still fail.
I think since it is some kind of deserialisation, it's better to do it there, then in the poll of the consumer.