dotnet-avro
dotnet-avro copied to clipboard
Support `IsRequired` attribute
Hi, me again with another question.
Is it possible to enforce nullability in schema of reference types?
This is our contract in code:
[DataContract(Name = "accountEvent")]
public class AccountEvent
{
[DataMember(Name = "id")]
public Guid Id { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "email")]
public string Email { get; set; }
[DataMember(Name = "confirmed")]
public bool Confirmed { get; set; }
[DataMember(Name = "phoneNumber", IsRequired = false)]
public string? PhoneNumber { get; set; } = null;
}
Schema registered in registry:
{
"type": "record",
"name": "accountEvent",
"fields": [
{
"name": "confirmed",
"type": "boolean"
},
{
"name": "email",
"type": "string"
},
{
"name": "id",
"type": {
"type": "string",
"logicalType": "uuid"
}
},
{
"name": "name",
"type": "string"
},
{
"name": "phoneNumber",
"type": "string"
}
]
}
I was trying to use IsRequired
but it didn't change anything (as expected after reading its documentation ;)).
What we would like to achieve is:
{
"name": "phoneNumber",
"type": [ "string", "null" ]
}
I'd like to help with implementing it - if you want help of course. Just let me know if that is possible or not because you'll probably know :)
We’re hoping to ship support for nullable reference types with 8.0.0 soon (see https://github.com/ch-robinson/dotnet-avro/issues/102). Currently, it’s all-or-nothing—you can set the resolver to follow .NET’s nullable semantics...
using Chr.Avro.Abstract;
using Chr.Avro.Confluent;
using Chr.Avro.Resolution;
using Confluent.Kafka;
using Confluent.SchemaRegistry;
var registry = new CachedSchemaRegistryClient(new SchemaRegistryConfig { ... });
var typeResolver = new ReflectionResolver(
resolveReferenceTypesAsNullable: true // schema builder will produce ["null", ...] for all reference types
);
var schemaBuilder = new SchemaBuilder(typeResolver: typeResolver);
var serializerBuilder = new SchemaRegistrySerializerBuilder(registry, schemaBuilder: schemaBuilder)
var producerBuilder = new ProducerBuilder<Ignore, SomeValue>();
await builder.SetAvroValueSerializer(serializerBuilder, "test-subject", registerAutomatically: AutomaticRegistrationBehavior.Always);
... but there isn’t a way to pick and choose fields short of modifying the abstract schema.
It’d be nice to support [IsRequired]
as well. I’m leery of possible contradictions with nullable types (e.g. https://stackoverflow.com/a/7767083), but I think they can both be implemented with an IsNullable
property on FieldResolution
.