Skip to content

feat(v3): support receiving multiple messages per operation (#333) - #336

Merged
lerenn merged 1 commit into
mainfrom
feat/333-receive-multiple-messages
Jun 14, 2026
Merged

lerenn merged 1 commit into
mainfrom
feat/333-receive-multiple-messages

Conversation

@lerenn

@lerenn lerenn commented Jun 14, 2026

Copy link
Copy Markdown
Owner

Closes #333. Follow-up to #140/#332 (which shipped the send side); this completes the receive side.

What changed

When a receive operation (or its channel) declares more than one message, the generator now produces one subscribe function per message instead of silently handling only the first one.

  • Per-message API: SubscribeToXForUserCreated(ctx, fn) / SubscribeToXForUserDeleted(ctx, fn), one callback per message type, plus matching UnsubscribeFromXFor... functions and per-message methods on the subscriber interface. Single-message operations are unchanged (byte-identical output).
  • Subscription rework: a single broker subscription is opened per channel address and multiplexed to the registered per-message handlers (held behind a *messageDispatcher so the controller stays copy-safe). Several per-message subscriptions on one channel no longer collide, and the broker subscription is canceled once the last message type is unsubscribed.
  • Discrimination: try-each-until-valid — each received message is unmarshalled and validated against every candidate schema (via go-playground/validator, already a dependency) and dispatched to the first match. Heuristic and best when messages have distinguishing required / enum / const fields, as acknowledged in AsyncAPI v3: support receiving multiple messages per operation (follow-up to #140) #333.
  • No-match policy: a message matching none of the expected types is Naked and surfaced through the error handler as the new extensions.ErrNoMatchingMessage, consistent with the existing processing-error path.

This also completes the UserController receive side of the #140 fixture, which previously only handled the first message.

Design decisions

The two open decisions in the issue were resolved as: single subscription + multiplex (keeps single-message output byte-identical; one broker subscription per channel) and Nak + errorHandler for unmatched messages (consistent with the existing error path; users can override via WithErrorHandler).

Tests

test/v3/issues/333 is a broker-backed regression test covering: dispatch of two distinct message types on one channel, the no-match (Nak + ErrNoMatchingMessage) path, and per-message unsubscribe. Passes with -race.

Notes

  • Generated code for multi-message receive channels now imports go-playground/validator/v10; documented in the README.
  • The 130/requestreply and 186 golden files have a trivial cosmetic whitespace change (closing } was previously jammed onto the next function's doc comment); behavior is identical.

🤖 Generated with Claude Code

Follow-up to #140/#332, which shipped the send side. When a receive
operation (or its channel) declares more than one message, generate one
subscribe function per message instead of silently handling only the
first one:

- SubscribeToXForUserCreated / SubscribeToXForUserDeleted, with one
  callback per message type, plus matching UnsubscribeFromXFor... and
  per-message methods on the subscriber interface. Single-message
  operations are unchanged (byte-identical output).
- A single broker subscription is opened per channel and multiplexed to
  the registered per-message handlers, so several per-message
  subscriptions on one channel no longer collide.
- Received messages are discriminated with a try-each-until-valid
  strategy (unmarshal + validate against each candidate schema using
  go-playground/validator) and dispatched to the first match.
- A message matching none of the expected types is nacked and surfaced
  through the error handler as the new extensions.ErrNoMatchingMessage.

Adds a broker-backed regression test (test/v3/issues/333) covering
dispatch of two distinct message types on one channel, the no-match
path, and per-message unsubscribe. Documents the behavior and the
validator dependency in the README.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@lerenn
lerenn merged commit 94edeae into main Jun 14, 2026
5 checks passed
@lerenn
lerenn deleted the feat/333-receive-multiple-messages branch June 14, 2026 14:43
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.

AsyncAPI v3: support receiving multiple messages per operation (follow-up to #140)

1 participant