Skip to content

feat(asyncapi): add AsyncAPI 3.1.0 parsing package - #9

Open
MarkRosemaker wants to merge 2 commits into
masterfrom
claude/asyncapi-parsing-repo-jnqk82
Open

feat(asyncapi): add AsyncAPI 3.1.0 parsing package#9
MarkRosemaker wants to merge 2 commits into
masterfrom
claude/asyncapi-parsing-repo-jnqk82

Conversation

@MarkRosemaker

Copy link
Copy Markdown
Owner

What

Adds a parsing library for AsyncAPI 3.1.0 that does for event-driven API specs what this repository does for OpenAPI: parse, validate, format and write specifications while preserving the order of every map.

It is a self-contained Go module (github.com/MarkRosemaker/asyncapi, own go.mod, go.sum, vendor/, LICENSE, README.md, .github/dependabot.yml) that lives in the asyncapi/ subdirectory. It is written so it can be moved into its own repository verbatim — git subtree split/mv and it builds unchanged. I kept it here because this session only has push access to MarkRosemaker/openapi; say the word if you'd rather have it split out.

Design

The package deliberately mirrors the openapi package, so both can be read and used side by side:

openapi asyncapi
one file per specification object same
ordered maps via MarkRosemaker/ordmap same
errors via MarkRosemaker/errpath same
JSON v2 with inlined specification extensions same
LoadFromFile/LoadFromData/LoadFromReader (+ …JSON/…YAML) same
Validate, SortMaps, WriteToFile, ToJSON, WriteJSON same
references resolved while loading, refOrValue[T] same

Dependency set and Go version are identical to the openapi module.

Objects covered

  • Document, Info, Contact, License, Tags, ExternalDocs
  • Servers, ServerVariables, Protocol
  • Channels, Messages, MessageTraits, MessageExamples, Parameters
  • Operations, OperationTraits, OperationReply, OperationReplyAddress
  • CorrelationID, RuntimeExpression
  • SecurityScheme, OAuthFlows
  • Bindings for all 20 protocols
  • Components with all 19 of its fixed fields
  • Schema and AnySchema

Notable decisions

  • AnySchema models the places where the spec allows Multi Format Schema Object | Schema Object | Reference Object. Without a schemaFormat the object is parsed as an AsyncAPI Schema; with an AsyncAPI schema format the inner schema is parsed too; any other format (Avro, Protobuf, RAML, …) is kept as a raw value so nothing is lost on write.
  • Boolean schemas (true/false, e.g. additionalProperties: false) are supported via Schema.Boolean and written back as booleans.
  • Schema.Type accepts a single type as well as a list of types and marshals back in the form it was given.
  • Reference chains are resolved: an operation referring to #/channels/x/messages/y, which is itself a $ref to #/components/messages/y, resolves to the message object.
  • ErrMustBeReference enforces the places where the spec requires a Reference Object rather than the object itself (operation.channel, operation.messages, channel.servers, reply.channel).
  • Bindings are kept as raw JSON values keyed by protocol, since their contents are defined by the separate bindings spec; unknown protocol keys are rejected, x- keys are allowed.
  • Format is not rejected when unknown — the spec explicitly calls it an open string-valued property. Format.IsKnown() reports whether it is one of the documented formats.

Tests

go test ./... passes, 86.1% coverage. Fixtures are the official example documents from asyncapi/spec@v3.1.0 (simple, anyof, correlation-id, operation-security, rpc-client, streetlights-kafka, streetlights-mqtt, request-reply), each stored as YAML plus the JSON the library writes, so every example is checked to survive a load → validate → write round trip in both directions. On top of that there are tests for reference resolution, the must-be-a-reference rules, validation error paths, multi format and boolean schemas, bindings, ordered maps and specification extensions.

One intentional normalization: a URL with an empty fragment (…/schema#) is written back without the trailing #, because these fields are parsed into *url.URL (same as jsonSchemaDialect in the openapi package).

🤖 Generated with Claude Code

https://claude.ai/code/session_01FJ5kGVz51ZGKSFuUSx7kaD


Generated by Claude Code

claude added 2 commits August 2, 2026 12:22
Add a self-contained Go module `github.com/MarkRosemaker/asyncapi` under
asyncapi/ that does for AsyncAPI what this repository does for OpenAPI:
parse, validate, format and write specifications while preserving the
order of every map.

The package mirrors the structure and the conventions of the openapi
package (one file per object, ordered maps via ordmap, errors via
errpath, JSON v2 with inlined specification extensions, YAML and JSON
loaders, reference resolution during loading):

- Document, Info, Contact, License, Tags and External Documentation
- Servers, Server Variables and Protocols
- Channels, Messages, Message Traits, Message Examples and Parameters
- Operations, Operation Traits, Operation Replies and Reply Addresses
- Correlation IDs and Runtime Expressions
- Security Schemes and OAuth Flows
- Bindings of all protocols, kept as raw values
- Components with all nineteen of its fixed fields
- Schemas, including boolean schemas, multiple types and Multi Format
  Schema Objects, whose non-AsyncAPI schemas are kept as they are

References are resolved while loading, including references that point
to other references, e.g. an operation that refers to a message of a
channel which in turn refers to a message of the components object.

Tests load the example documents of the specification and check that
they survive a round trip, that references are resolved and that
validation reports the exact location of a problem.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FJ5kGVz51ZGKSFuUSx7kaD
Follow-up on three fronts.

Documentation: every exported type now carries a link to the section of
the AsyncAPI 3.1.0 specification it implements, and the rules that are
enforced are quoted where they are enforced. A package documentation
gives an overview of reading, validating and writing a document. Every
anchor was cross-checked against the specification source, and every
fixed field of every object as well as all 35 JSON Schema keywords
listed in the Schema Object section are covered by the types.

Validation: the rules that a document can break without being
syntactically wrong are checked now.

- the identifier of the document must conform to the URI format
- every URL the specification declares as absolute must be one
- a channel address must not use query parameters or fragments
- the keys of the parameters of a channel must match the pattern of the
  Parameters Object
- the messages of an operation and of an operation reply must be a
  subset of the messages of the channel they refer to
- the servers of a channel of the root Channels Object must be servers
  of the root Servers Object, and the channel of an operation of the
  root Operations Object must be a channel of the root Channels Object
- the version suffix must be alphanumeric

A reference object also no longer rejects additional properties, since
the specification demands that they SHALL be ignored.

Marshalling: a document can now be written as YAML as well as JSON,
via WriteYAML, ToYAML or WriteToFile with a .yaml or .yml path.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FJ5kGVz51ZGKSFuUSx7kaD
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.

2 participants