I'm trying to use avro schema registry with multiple schema types per topic, as discussed in this blog post: https://www.confluent.io/blog/put-several-event-types-kafka-topic/
It mentions setting key.subject.name.strategy and value.subject.name.strategy to one of 3 options:
io.confluent.kafka.serializers.subject.TopicNameStrategy
io.confluent.kafka.serializers.subject.RecordNameStrategy
io.confluent.kafka.serializers.subject.TopicRecordNameStrategy
I'd like to set it to TopicRecordNameStrategy, but I can't figure out how to do this with the .net client. Is it possible?
no, we haven't added this functionality yet. it won't make it into 1.0, but we'll add it after.
PR #585 had covered this, but it is outdated from the 1.0 api changes. I have a fork that I've been using to get around it https://github.com/jblackburn21/confluent-kafka-dotnet/tree/avro-subject-name-strategy
also, IIRC we have more than one customer asking for this, and it's a quick win, so I expect it will get done fairly soon after the 1.0 API is finalized.
Can you tell when multiple Avro schemas per topic will be supported by your dotnet client?
@mhowlett - I'm looking into this at the moment and have something that basically works. Is the approach below anything like what you are planning? If not, can you tell me your design approach? I'd ideally like not to stray too far from the beaten path.
Thanks.
I'm using custom serializers based on SchemaRegistry.serdes and using the schema subject in the message to discriminate the type for deserialization. For the producer and consumer, don't set a serializer or deserializer when building the producer/consumer - produce and consume binary.
Internally I have a registry of subject, version and C# Type.
For serialization, use the type to look up the subject and version and find the target schema. Then create the right serializer and produce the binary message.
For deserialization, get the schema id from the message, look up the subject and version from the schema registry, and use these to look up the target type for the deserializer.
@paddypawprints I'm trying to do this exact thing, while waiting for the official implementation.
Would you have any example code to share?
We also have a strong interest in this. The original posting is asking specifically about the inclusion of the new configuration values for the schema registry client. I am also interested in any plans to allow support for multiple deserializers for a single topic. Are there any plans on the horizon to allow a consumer to register multiple deserializers?
Not sure exactly what your requirements are, but you could easily write a IDeserializer<object> and return different types based on the data, or just parse byte[] data inline in your consume loop. At some point you need to do a switch on type, and we decided a standard framework for this was not worth including in the library. Feel free to demonstrate an API you'd like to see if not the above.
Thanks for the suggestion! I'll look into it and do some thought on an API.
@mhowlett - thanks for the feedback.
Here is where I'm up to. I'm checking internally whether I can put the code up on GitHub. Until that happens if you are interested mail me at patrick.[email protected] for details
It isn't production code by any means but seems to work ok in testing so far.
@mhowlett
Am i right in interpreting the position of the confluent-kafka-dotnet team as
"dont use the schema registry in .net if you have multiple types per topic"
if i have misunderstood sorry, but i was hoping we could use the schema registry and get all the schema evolutionary benefits etc.
you can't at the moment. we will add support in the future, quite likely early Q3.
Hi @mhowlett,
Sorry to bang on about this, but I'm rolling out a new product soon and want to try and be as backwards compatible as possible from a serialization point of view.
I'm still not 100% clear on what I should do.
Above you mentioned :
"Not sure exactly what your requirements are, but you could easily write a IDeserializer
Are you talking about using Avro here ?
My thinking is that I should be using Avro (currently using JSON), but I'm not 100% clear on how I'd manage the deserialization where I have multiple Schemas/Types per Topic.
Is there any pseudocode or a simple example you could point me too ?
I've been looking through the source code, but my Avro knowledge is not great,
Trying to adapt this:
https://github.com/confluentinc/confluent-kafka-dotnet/blob/master/src/Confluent.SchemaRegistry.Serdes/GenericDeserializerImpl.cs#L57
Would I basically in a loop do something like this:
using (var stream = new MemoryStream(array))
using (var reader = new BinaryReader(stream))
{
var writerId = IPAddress.NetworkToHostOrder(reader.ReadInt32());
var writerSchemaJson = await schemaRegistryClient.GetSchemaAsync(writerId).ConfigureAwait(continueOnCapturedContext: false);
var writerSchema = global::Avro.Schema.Parse(writerSchemaJson);
var message = datumReader.Read(default(**object**), new BinaryDecoder(stream));
}
So i'm not sure where I'll be able to cast the message above to the object I want.
I could maybe switch on the object.
switch(message)
{
case User:
case Order:
case Product:
}
Am I going down the right path here ?
Thanks...
@mhowlett
I've got a example running here:
https://github.com/mickdelaney/kafka-spike/
basically the SerDe stuff is here:
https://github.com/mickdelaney/kafka-spike/blob/master/src/Core/Kafka/AvroSubjectNameStrategyDeserializer.cs#L77
https://github.com/mickdelaney/kafka-spike/blob/master/src/Core/Kafka/SubjectNameSerializer.cs#L66
Using:
https://github.com/mickdelaney/kafka-spike/blob/master/src/Core/Kafka/SubjectNameFactory.cs
https://github.com/mickdelaney/kafka-spike/blob/master/src/Core/Kafka/SubjectNameSchemaCache.cs
And Usage Wise Its a Switch On Object.
https://github.com/mickdelaney/kafka-spike/blob/master/src/Core/Domain/Users/UserConsumer.cs#L51
@mhowlett we’ve gone with Avro Unions per topic for now.
@mhowlett I noticed you said this feature will be available "more likely early Q3". has this been released already? if not, do you have a new timeline? My team also needs this feature for a project we are working on.
sorry, it's not done yet. commonly requested, it's coming.
Hi,
I've also been watching this space, can you forecast a date ?
additional +1 noted
which version of confluent will support multi Avro schema to one topic? is there any date planned.
Watching this as well.
it'll be in 1.3 for sure. i hope to get it merged to master this week.
just merged #1070 to master. expect to do a 1.3-PRE1 release that includes this later this week based on librdkafka 1.2.1, also due later this week.
@mhowlett thanks for all you great work on this! This was one gap I was hoping to see filled before my company got moving forward with our event driven architecture journey.
I was wondering, will there be any follow up to this on the consumer side to provide something similar to the AvroSubjectNameStrategyDeserializer @mickdelaney built? Something to allow the consumer to deserialize using Avro based on the SubjectNameStrategy? I didn't see any code or issues pointing to this. If I am missing it could please point me in the right direction? Maybe it is easy/possible to do with everything that is currently int he library and I am just not seeing how to piece it together. Any info would be much appreciated!
@mhowlett I tried this feature with 1.3 RC1 on the consumer side, but still didnt get it working. I was expecting that I could use something like .SetValueDeserializer(new AvroDeserializer
Could you please provide an example of how the consumer can be written to consume multiple events that has different schemas ?
@mhowlett is it an option to implement SpecificDeserializer with a constructor that will take for example HashSet<Avro.Schema>. So it will be the collection of the reader's schemas. Then you could just do something like this:
var readerSchema = _readerSchemas.FirstOrDefault(schema => schema.Name == writerSchema.Name);
It will allow for deserializing multiple event types per topic. Deserializer will return an object type. Then you can perform simple type check
object is %yourType%
it's an option (i think it wouldn't be too hard, you can always write a custom serializer). I'd prefer an API with strong type checking though. I do want to make a producer without type parameters, and here's the reason you might want that on the consumer. You could then perhaps have TryConsume<K,V> methods (and C# can infer the K,V, so they don't need to be specified which is nice). anyway, that's not going to be done imminently. making a custom deserializer as you suggest sounds like a good idea.
additional +1 noted
My team is also looking for this update. Please let us know when this is gonna be released. Thank You!
is there documentation on this feature now that 1.3 is released?
Hi All, I have gone through this post but not able to figure out - how to create a avro schema from a C# class? - Any help on this.
Hi Pabi,
I did some work on this - see here https://github.com/paddypawprints/schemagen
It uses Roslyn to parse c# and generate an avro schema (or protocol). If you build it the program has a —help option.
It is parked here and I am trying to clean it up to contribute it to the avro project. I’d appreciate any comments you have if this work is interesting to you.
Sent from my iPad
On Dec 23, 2019, at 1:56 AM, Pabi171 notifications@github.com wrote:

Hi All, I have gone through this post but not able to figure out - how to create a avro schema from a C# class? - Any help on this
comments You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHubhttps://github.com/confluentinc/confluent-kafka-dotnet/issues/746?email_source=notifications&email_token=AFCP6V62MNZNU5EYGL5C55LQ2CDOHA5CNFSM4GRDFJ5KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHQXZXQ#issuecomment-568425694, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AFCP6V7FEJXWEZPIQLIMGFTQ2CDOHANCNFSM4GRDFJ5A.o
thanks for your efforts @paddypawprints - there are various other similar efforts to make a better avro implementation about as well.
i want to note here that protobuf and json support is coming to SR, and i expect to be adding .net client support for this this quarter. These formats are a slight mismatch for the use case, but are close enough and have the benefit of having first class support in .net.
Any update for strategy support for C# client
Most helpful comment
also, IIRC we have more than one customer asking for this, and it's a quick win, so I expect it will get done fairly soon after the 1.0 API is finalized.