Summary
Add an option to s2cs (JSON Structure to C#) and a2cs (Avro to C#) commands that generates C# models compatible with OpenAPI Generator's output style.
Motivation
When integrating Avrotize-generated models with OpenAPI Generator-produced API clients, there's a structural mismatch:
| Aspect |
OpenAPI Generator |
Avrotize (current) |
| Property style |
Option<T> wrapper with dual accessors |
Simple auto-properties |
| Null tracking |
Explicit Option<T>.IsSet for not-set vs null |
Standard nullable types |
| JSON serialization |
Custom JsonConverter<T> with manual Read/Write |
Attribute-based ([JsonPropertyName]) |
| Validation |
IValidatableObject interface |
None |
This makes it difficult to use Avrotize as a drop-in replacement for OpenAPI Generator's model generation while still using OpenAPI Generator for API client scaffolding.
Proposed Solution
Add a new flag to both commands:
avrotize s2cs schema.struct.json --out ./models --openapi-generator-compat
avrotize a2cs schema.avsc --out ./models --openapi-generator-compat
When enabled, the generated C# classes would include:
-
Option<T> wrapper pattern for optional properties with dual accessors:
public Option<string?> BitlyUrlOption { get; private set; }
public string? BitlyUrl { get => BitlyUrlOption; set => BitlyUrlOption = new(value); }
-
Custom JSON converter per class for fine-grained serialization control
-
IValidatableObject implementation (can be empty initially)
-
Constructor accepting all properties as Option<T> parameters
Example Comparison
Current Avrotize output (284 lines for Gif.cs):
public partial class Gif
{
[JsonPropertyName("bitly_url")]
public string? BitlyUrl { get; set; }
// ...
}
With --openapi-generator-compat (matching OpenAPI Generator's 815 lines):
public partial class Gif : IValidatableObject
{
[JsonIgnore]
public Option<string?> BitlyUrlOption { get; private set; }
[JsonPropertyName("bitly_url")]
public string? BitlyUrl { get => BitlyUrlOption; set => BitlyUrlOption = new(value); }
// ...
}
public class GifJsonConverter : JsonConverter<Gif> { /* ... */ }
Benefits
- Enables using Avrotize for model generation while using OpenAPI Generator for API client scaffolding
- Preserves three-way null semantics (not-set vs explicitly-null vs value)
- Provides seamless interoperability without runtime mapping overhead
Additional Context
This came from investigating how to integrate oas2s (OpenAPI to JSON Structure) output with OpenAPI Generator's C# client. See analysis in PR #151.
Summary
Add an option to
s2cs(JSON Structure to C#) anda2cs(Avro to C#) commands that generates C# models compatible with OpenAPI Generator's output style.Motivation
When integrating Avrotize-generated models with OpenAPI Generator-produced API clients, there's a structural mismatch:
Option<T>wrapper with dual accessorsOption<T>.IsSetfor not-set vs nullJsonConverter<T>with manual Read/Write[JsonPropertyName])IValidatableObjectinterfaceThis makes it difficult to use Avrotize as a drop-in replacement for OpenAPI Generator's model generation while still using OpenAPI Generator for API client scaffolding.
Proposed Solution
Add a new flag to both commands:
When enabled, the generated C# classes would include:
Option<T>wrapper pattern for optional properties with dual accessors:Custom JSON converter per class for fine-grained serialization control
IValidatableObjectimplementation (can be empty initially)Constructor accepting all properties as
Option<T>parametersExample Comparison
Current Avrotize output (284 lines for Gif.cs):
With --openapi-generator-compat (matching OpenAPI Generator's 815 lines):
Benefits
Additional Context
This came from investigating how to integrate
oas2s(OpenAPI to JSON Structure) output with OpenAPI Generator's C# client. See analysis in PR #151.