Skip to content

fix(avro)!: support named type references#32

Merged
VisualBean merged 7 commits into
vnextfrom
alex/avro-named-types
Jun 8, 2026
Merged

fix(avro)!: support named type references#32
VisualBean merged 7 commits into
vnextfrom
alex/avro-named-types

Conversation

@VisualBean

@VisualBean VisualBean commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

About the PR

Adds Avro named type reference support for AsyncApiAvroSchema.

This introduces AvroNamedType for Avro schema references that are represented as plain Avro strings, such as "LongList", instead of AsyncAPI $ref objects. Named types are resolved using Avro name and namespace rules, including recursive references and map value schemas.

The PR also updates validation so unresolved Avro named types are reported as warnings, and fixes fragment diagnostics so validator warnings are returned in diagnostic.Warnings instead of being treated as errors.

Documentation for schema payloads and Avro named types was added in docs/Schemas.md.

Assigning primitives still works, but reading AvroMap.Values as AvroPrimitiveType now needs the explicit cast because the property type was widened.

Changelog

  • Add: Added AvroNamedType for Avro named schema references.
  • Add: Added recursive Avro named type deserialization and serialization support.
  • Add: Added Avro named type resolution using name and namespace rules.
  • Add: Added validation warnings for unresolved Avro named types.
  • Add: Added tests for recursive named types, map value named types, unresolved warnings, full-document parsing, and serialization.
  • Add: Added docs/Schemas.md with Avro named type documentation.
  • Change: Updated AvroMap.Values to accept any AsyncApiAvroSchema, not only primitive types.
  • Change: Updated Avro schema walking to traverse nested schemas structurally.
  • Fix: Fixed ReadFragment diagnostics so validation warnings are added to diagnostic.Warnings.

Related Issues

BREAKING CHANGE: AvroMap.Values now uses AsyncApiAvroSchema instead of AvroPrimitiveType.

Summary by CodeRabbit

  • New Features

    • Named Avro schema types now fully supported with automatic resolution and serialization capabilities
    • Explicit conversion operator enables casting Avro schemas to primitive type enumerations
  • Bug Fixes

    • Fixed infinite recursion detection during Avro schema graph traversal
    • Improved diagnostic handling: validation errors and warnings are now properly distinguished
  • Validation

    • Added validation rule to detect unresolved named schema references
  • Documentation

    • Comprehensive documentation for AsyncAPI.Net message payload schemas including Avro formats and practical examples

Adds a new job named Obfuscan to the CI workflow to scan the pull request diff using the ByteBardOrg/obfuscan-action.
This job runs only when a pull request is opened, and it uses the head SHA of the pull request to check for potential issues in the code changes before the main build proceeds.
Adds Avro-specific named type handling for schemas that reference previously defined records, enums, or fixed types by name.

Introduces `AvroNamedType`, keeps AsyncAPI `$ref` handling unchanged, supports recursive schemas like `LongList`, and widens map `values` to accept any Avro schema instead of only primitive types.

Existing construction with `AvroPrimitiveType` is preserved through the existing implicit conversion to `AsyncApiAvroSchema`, and primitive schema values can be converted back with an explicit cast.

BREAKING CHANGE: `AvroMap.Values` now uses `AsyncApiAvroSchema` instead of `AvroPrimitiveType`.
Changed how validation errors and warnings are added to the diagnostic collection. Previously, all items from the validation result were iterated over. This change explicitly separates the handling of AsyncApiValidatorError into diagnostic.Errors and AsyncApiValidatorWarning into diagnostic.Warnings, ensuring correct categorization of validation feedback.
@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR implements support for Avro named types (recursive and forward-referenced schemas) in AsyncAPI.NET, resolving issue #9. Changes span the data model, deserialization with instance-based registry, safe traversal with loop detection, validation rules, and comprehensive test coverage.

Changes

Avro Named Types Feature

Layer / File(s) Summary
Validation diagnostic splitting
src/ByteBard.AsyncAPI.Readers/AsyncApiJsonDocumentReader.cs
ReadFragment<T> now separates AsyncApiValidatorError from AsyncApiValidatorWarning items into diagnostic.Errors and diagnostic.Warnings respectively, enabling validation rules to emit warnings without them being treated as errors.
Named type data model
src/ByteBard.AsyncAPI/Models/Avro/AsyncApiAvroSchema.cs, src/ByteBard.AsyncAPI/Models/Avro/AvroMap.cs, src/ByteBard.AsyncAPI/Models/Avro/AvroNamedType.cs
New AvroNamedType class stores named schema references with optional target resolution. AvroMap.Values upgraded from AvroPrimitiveType to AsyncApiAvroSchema to support complex nested schemas. Explicit cast operator added to AsyncApiAvroSchema for converting primitive schemas to AvroPrimitiveType enum.
Deserialization with named-type registry
src/ByteBard.AsyncAPI.Readers/Schemas/AsyncApiAvroSchemaDeserializer.cs
Refactored from static ParseFields to instance-based deserializer maintaining namedTypes registry and namespace stack. Explicit property extraction replaces fixed-field maps; named schemas (record, enum, fixed) are registered during deserialization; metadata parsing centralized via ParseMetadata using property-name sets.
Safe schema traversal with loop detection
src/ByteBard.AsyncAPI/Services/AsyncApiWalker.cs
Added avroSchemaLoop stack for detecting and preventing infinite recursion. Walk(AsyncApiAvroSchema) now early-returns for already-visited schemas and traverses nested structures in records, arrays, maps, and unions.
Named type validation rule
src/ByteBard.AsyncAPI/Validation/Rules/AsyncApiAvroRules.cs
New NamedTypeMustResolve rule emits warnings when AvroNamedType instances have unresolved Target (null), indicating forward references to undefined named types.
Test coverage
test/ByteBard.AsyncAPI.Tests/Models/AvroSchema_Should.cs, test/ByteBard.AsyncAPI.Tests/Validation/ValidationRulesetTests.cs
Eight new test methods covering recursive named-type round-trip (deserialize/serialize), named types in map values, unresolved named type warnings, and primitive type conversion. Default ruleset test updated from 28 to 29 expected rules.
Schema documentation
docs/Schemas.md
Complete guide to AsyncAPI.Net schemas including JSON Schema and Avro payload types, AvroNamedType naming/resolution rules with examples, Avro construction usage example demonstrating records, fields, arrays, maps, unions, and fixed types. Custom schema parser implementation guide via ISchemaParser interface and ParseNode deserialization patterns.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • ByteBardOrg/AsyncAPI.NET#29: Both PRs modify the diagnostic flow in AsyncApiJsonDocumentReader.ReadFragment<T>, with this PR splitting validation results into errors vs. warnings while that PR propagates SpecificationVersion through the same code path.

Poem

🐰 Recursive types now hop through named schemas with glee,
No more infinite loops—the walker ensures clarity!
Named type registries track each forward reference true,
And validation warns when a schema's undefined too.
AsyncAPI's Avro now supports the full recursive dance! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.13% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding support for Avro named type references.
Linked Issues check ✅ Passed The PR fully addresses issue #9 by implementing AvroNamedType with recursive support, name/namespace resolution, and validation handling for unresolved named types.
Out of Scope Changes check ✅ Passed All changes are directly related to issue #9: adding AvroNamedType support, improving schema deserialization, fixing fragment diagnostics, and adding documentation.
Description check ✅ Passed PR description comprehensively covers objectives, changes, and breaking changes with clear structure and detail.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch alex/avro-named-types

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@VisualBean VisualBean changed the title Avro named types fix(avro)!: support named type references Jun 8, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/Schemas.md`:
- Line 91: Update the wording to use compound-modifier hyphenation: replace the
phrase “named type references” with “named-type references” in the sentence
describing Avro named schemas so the text reads that Avro named schemas can be
referenced by name using AvroNamedType and that these are named-type references
(serializing as plain strings like "LongList", not AsyncAPI $ref objects).
- Line 11: Fix several documentation typos in the Schemas doc: change
"convertable" to "convertible" in the sentence referencing AsyncApiJsonSchema
and AsyncMultiFormatSchema (look for the phrase "AsyncApiJsonSchema is
implicitly convertable to AsyncMultiFormatSchema"), remove the stray "to" in the
phrase "attaching it via to" (make it "attaching it via"), change "parts that
needs" to "parts that need", correct "propery" to "property", and change "its
looks" to "it looks". Search for those exact typo strings to locate the places
to edit and apply the replacements so spelling and grammar are fixed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3293fe74-0de2-4d93-b679-9b01702b2be2

📥 Commits

Reviewing files that changed from the base of the PR and between b79d6bb and 0274249.

📒 Files selected for processing (10)
  • docs/Schemas.md
  • src/ByteBard.AsyncAPI.Readers/AsyncApiJsonDocumentReader.cs
  • src/ByteBard.AsyncAPI.Readers/Schemas/AsyncApiAvroSchemaDeserializer.cs
  • src/ByteBard.AsyncAPI/Models/Avro/AsyncApiAvroSchema.cs
  • src/ByteBard.AsyncAPI/Models/Avro/AvroMap.cs
  • src/ByteBard.AsyncAPI/Models/Avro/AvroNamedType.cs
  • src/ByteBard.AsyncAPI/Services/AsyncApiWalker.cs
  • src/ByteBard.AsyncAPI/Validation/Rules/AsyncApiAvroRules.cs
  • test/ByteBard.AsyncAPI.Tests/Models/AvroSchema_Should.cs
  • test/ByteBard.AsyncAPI.Tests/Validation/ValidationRulesetTests.cs

Comment thread docs/Schemas.md Outdated
Comment thread docs/Schemas.md Outdated
@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown

obfuscan report

Status: No findings.

Metric Value
Scanned files 9
Findings 0
Block 0
Warn 0
Info 0
Duration 28 ms
Engine 0.2.0
Rules 2026.04.0

No suspicious obfuscation or backdoor patterns were found in the scanned diff.

@VisualBean VisualBean merged commit 310868a into vnext Jun 8, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Avro implementation does not support defined named types

1 participant