Skip to content

#1587 Support routing for Message<T> parameters in @SqsHandler - #1644

Open
alexisgra wants to merge 1 commit into
awspring:mainfrom
alexisgra:1587-route-message-envelope-payload-in-sqs-handler
Open

#1587 Support routing for Message<T> parameters in @SqsHandler#1644
alexisgra wants to merge 1 commit into
awspring:mainfrom
alexisgra:1587-route-message-envelope-payload-in-sqs-handler

Conversation

@alexisgra

Copy link
Copy Markdown
Contributor

📢 Type of change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring

📜 Description

When using @SqsListener with multiple @SqsHandler methods, routing is unable to route messages to a handler with Message<T> envelope as parameter.

The cause is in CompositeInvocableHandler.isPayloadAssignable: for a Message<T> parameter it compared
the payload against Message.class, which never matches a concrete payload. So the handler was never selected. Following Tomas comment in #1587 , the fix detects a Message typed parameter and resolves its generic type, then matches the payload against that generic instead.

⚠️ Known breaking change — open for discussion.

Because a Message<T> parameter is now considered payload-assignable, a single handler that declares both the Pojo and its Message (the workaround suggested in #1587) now resolves two payload-assignable parameters and throws "Ambiguous payload parameter for ..." instead of routing on the Pojo.

Handler (payload = Pojo) Before This PR
handle(Pojo) matches 🟢 matches 🟢
handle(Message<Pojo>) no match 🔴 matches 🟢
handle(Pojo, Message<Pojo>) matches 🟢 throws (breaking change) ⚠️

A change in findCandidate method can make the last case route on the Pojo again (treat Message<T> as the
envelope, not a second payload). I've left it out so you can decide the intended semantics.
The behavior is pinned by throwsWhenPayloadAndMessageParametersOnSameMethod.

💡 Motivation and Context

Fix #1587

💚 How did you test it?

  • Added unit tests in CompositeInvocableHandlerTest covering :

    • Message<T> routing.
    • Ambiguity across handlers when a plain and a Message<T> handler match the same payload type.
    • Ambiguity within one method declaring both a plain and a Message<T> parameter of the same type.
  • Added integration test in SqsIntegrationTests, asserting a Message<String> handler is selected and the default handler is not invoked.

📝 Checklist

  • I reviewed submitted code
  • I added tests to verify changes
  • I updated reference documentation to reflect the change
  • All tests passing
  • No breaking changes

🔮 Next steps

Decide the intended behavior for a handler declaring both a Pojo and a Message<Pojo> as parameters:

  1. Keep it as an ambiguity error (current behavior - breaking change)
  2. Route on the Pojo and treat the Message<T> as the envelope.

In my opinion, handle(Message<Pojo>) should now replace handle(Pojo, Message<Pojo>); the dual-parameter
form becomes redundant once the envelope routes on its own. However, since the workaround was publicly
documented, I understand you may prefer to avoid a breaking change here.

I'm happy to push an adjustment for 2, if that's preferred.

@github-actions github-actions Bot added component: sqs SQS integration related issue type: documentation Documentation or Samples related issue labels Jun 30, 2026

@tomazfernandes tomazfernandes 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.

Thanks for the PR @alexisgra, looks good.

I'm happy to push an adjustment for 2, if that's preferred.

Yes, let's keep backwards compatibility. The specific semantics would be a plain payload parameter match should take precedence. Message parameters only participate in routing when no plain parameter matches the payload. That keeps every configuration that routes today routing identically.

We should be good to merge then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: sqs SQS integration related issue type: documentation Documentation or Samples related issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support @SqsHandler routing for Message<T> parameters

2 participants